gpt4 book ai didi

iphone - 消息发送到已解除分配的实例问题

转载 作者:行者123 更新时间:2023-12-03 21:06:59 24 4
gpt4 key购买 nike

过去几个小时我一直在调试以下问题,但似乎无法得出一个好的结论。

-[NSIndexPath row]: message sent to deallocated instance 0x506cf90

我正在 UITableView 上的每个单元格上实现一个滑动识别器。每当检测到滑动时,就会调用下面的代码。它的作用是显示/隐藏单元格中的 subview 。如果 subview 已经显示,则隐藏,否则显示。如果 subview 已显示在单元格 5 上,并且在单元格 3 上检测到滑动,那么我们首先删除该 subview ,然后在单元格 3 上添加 subview 。

我尝试了下面的代码,它似乎适用于某些单元格。但是,特别是在 UITableView 底部有一个单元格,如果我尝试隐藏 subview ,则会出现上述错误。它对于其他单元格(仅是底部的单元格)来说效果非常好。这是为什么?

代码如下:

- (void)swipe:(UISwipeGestureRecognizer *)recognizer direction:(UISwipeGestureRecognizerDirection)direction
{
if (recognizer && recognizer.state == UIGestureRecognizerStateEnded)
{
// Get the table view cell where the swipe occured
CGPoint location = [recognizer locationInView:self.table];
NSIndexPath* indexPath = [self.table indexPathForRowAtPoint:location];
ConvoreCell* cell = (ConvoreCell *) [self.table cellForRowAtIndexPath:indexPath];

[self.table beginUpdates];

NSLog(@"ROW is %d", global.row);
//removing the options view at the other cell before adding a new one
if (global != nil && global.row != indexPath.row){
[sideSwipeView removeFromSuperview];
[sideSwipeView release];
sideSwipeView = nil;
}

//options already exist, we need to remove it
if (sideSwipeView != nil){
[sideSwipeView removeFromSuperview];
[sideSwipeView release];
sideSwipeView = nil;
slide = NO;
} else {
//options do not exist and therefore we need to add it
NSArray * buttonData = [[NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:@"Mark Read", @"title", @"mark.png", @"image", nil],
[NSDictionary dictionaryWithObjectsAndKeys:@"Track", @"title", @"play.png", @"image", nil],
[NSDictionary dictionaryWithObjectsAndKeys:@"Leave", @"title", @"delete.png", @"image", nil],
nil] retain];

NSMutableArray * buttons = [[NSMutableArray alloc] initWithCapacity:buttonData.count];
sideSwipeView = [[UIView alloc] initWithFrame:CGRectMake(0, cell.frame.size.height-25, 320, 25)];
[sideSwipeView setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin];
[sideSwipeView setBackgroundColor:[UIColor colorWithPatternImage: [UIImage imageNamed:@"dotted-pattern.png"]]];
[sideSwipeView setTag:-10];

CGFloat leftEdge = BUTTON_LEFT_MARGIN;
for (NSDictionary* buttonInfo in buttonData)
{
if (!([[buttonInfo objectForKey:@"title"] isEqualToString:@"Mark Read"] && [[[groups objectAtIndex:indexPath.row] unread] intValue] == 0))
{

UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];

button.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin;

UIImage* buttonImage = [UIImage imageNamed:[buttonInfo objectForKey:@"image"]];
if ([[[groups objectAtIndex:indexPath.row] tracked] intValue] == 1 && [[buttonInfo objectForKey:@"title"] isEqualToString:@"Track"]){
buttonImage = [UIImage imageNamed:@"pause.png"];
[button setSelected:YES];
} else
[button setSelected:NO];

button.frame = CGRectMake(leftEdge, 0, buttonImage.size.width, buttonImage.size.height);

UIImage* grayImage = [self imageFilledWith:[UIColor colorWithWhite:0.9 alpha:1.0] using:buttonImage];
[button setImage:grayImage forState:UIControlStateNormal];

if ([[buttonInfo objectForKey:@"title"] isEqualToString:@"Mark Read"]){
[button addTarget:self action:@selector(markRead:) forControlEvents:UIControlEventTouchUpInside];
} else if ([[buttonInfo objectForKey:@"title"] isEqualToString:@"Track"]){
[button addTarget:self action:@selector(track:) forControlEvents:UIControlEventTouchUpInside];
} else if ([[buttonInfo objectForKey:@"title"] isEqualToString:@"Leave"]){
[button addTarget:self action:@selector(leave:) forControlEvents:UIControlEventTouchUpInside];
}
[button setTag:indexPath.row];
[buttons addObject:button];

[sideSwipeView addSubview:button];
leftEdge = leftEdge + buttonImage.size.width + BUTTON_SPACING;
}
}

[cell.contentView addSubview:sideSwipeView];
[buttons release];
[buttonData release];
global = indexPath;
slide = YES;

}
[self.table endUpdates];
[self.table deselectRowAtIndexPath:indexPath animated:YES];

}
}

现在的问题是指向indexPath 的指针以某种方式被释放。我可以通过制作 indexPath 的副本而不是仅仅引用指针来解决这个问题。所以我这样做了:

global = [indexPath copy];

出于某种原因,在调用此方法后,它会释放 indexPath,但我不确定是谁执行的。我认为 iOS 会执行此操作...这是真的吗?

最佳答案

    NSIndexPath* indexPath = [self.table indexPathForRowAtPoint:location];

返回一个自动释放的实例。所以,是的,您对 global 的分配需要保留该对象。 copy 有效地返回保留的实例。

不过,不要泄漏。如果你这样做:

global = [indexPath copy];

如果你不先释放 global 的原始值,就会发生泄漏。

哦,还有:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

关于iphone - 消息发送到已解除分配的实例问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6165481/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com