设置cell.imageView.image时的objc_msgsend

时间:2010-03-08 15:53:25

标签: iphone

此代码正常工作,直到我开始滚动:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}

Route *r = [data routeForDay:day index:indexPath.row];
cell.textLabel.text = r.name;
cell.imageView.image = r.image;

return cell;
}

它适用于每一行,直到我向下滚动,当它与cell.imageView.image = r.image上的objc_msgsend崩溃时;我已经确认没有什么是零,我甚至检查了retainCount所涉及的一切。我完全不知所措,有什么想法吗?感谢。

修改

我解决了这个问题,但是不明白代码的变化是如何让bug消失的,所以如果有人知道的话,我会很感激。

这是最初在Route init方法中创建图像的方式。在我的tableview控制器中滚动表时,图像被取消分配。

NSString *imagePath = [[NSBundle mainBundle] pathForResource:[dict valueForKey:@"image"] ofType:@"png"];
image = [UIImage imageWithContentsOfFile:imagePath];

当我将第二行更改为

image = [[UIImage alloc] initWithContentsOfFile:imagePath];

它运作良好。

我只是有点困惑和不快乐。

1 个答案:

答案 0 :(得分:3)

您的错误肯定是保留/释放问题。试着打开僵尸。如果您不知道如何操作,请参阅下文并阅读this tech note

我假设datarr.image指向的某个对象未正确保留。

还有一件事:在深入了解内存管理(尤其是自动释放池)之前,请不要查看retainCount。否则,您只会被返回的值混淆。

如何启用僵尸:

  

选择项目>编辑Active Executable以打开可执行信息窗口   单击“参数”   单击“要在环境中设置的变量”部分中的添加(+)按钮   在“名称”列中输入NSZombieEnabled,在“值”列中输入“是”   确保选中NSZombieEnabled条目的复选标记。

修改

恭喜发现错误。你仍然缺少这个谜题的唯一方法是了解Cocoa的内存管理。我建议您阅读the official documentation,因为它简洁易读。

简而言之:imageWithContentsOfFile:返回一个自动释放的对象,而initWithContentsOfFile:返回一个保留的对象。但同样:阅读文档,否则你将继续遇到内存错误。