此代码正常工作,直到我开始滚动:
- (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];
它运作良好。
我只是有点困惑和不快乐。
答案 0 :(得分:3)
您的错误肯定是保留/释放问题。试着打开僵尸。如果您不知道如何操作,请参阅下文并阅读this tech note。
我假设data
,r
或r.image
指向的某个对象未正确保留。
还有一件事:在深入了解内存管理(尤其是自动释放池)之前,请不要查看retainCount
。否则,您只会被返回的值混淆。
如何启用僵尸:
选择项目>编辑Active Executable以打开可执行信息窗口 单击“参数” 单击“要在环境中设置的变量”部分中的添加(+)按钮 在“名称”列中输入NSZombieEnabled,在“值”列中输入“是” 确保选中NSZombieEnabled条目的复选标记。
修改强>
恭喜发现错误。你仍然缺少这个谜题的唯一方法是了解Cocoa的内存管理。我建议您阅读the official documentation,因为它简洁易读。
简而言之:imageWithContentsOfFile:
返回一个自动释放的对象,而initWithContentsOfFile:
返回一个保留的对象。但同样:阅读文档,否则你将继续遇到内存错误。