Subclassed UITableViewCell创建Zombie除非保留

时间:2011-04-29 16:10:35

标签: iphone uitableview nszombie

我用自定义nib创建了一个UITAbleViewCell子类,并在我的应用程序中的两个不同的UITableViews中使用它。它在其中一个表中完美运行,但是当我用力滚动它时,另一个表崩溃了。 Instruments在此代码中标识了一个僵尸(在cellForRowAtIndexPath中):

NSString *identifier = @"edit";
LogTableCell *cell = (LogTableCell*)[tableView dequeueReusableCellWithIdentifier:identifier];

if (!cell) {
   cell = (LogTableCell*) [[[NSBundle mainBundle] loadNibNamed:@"LogTableCell" owner:self options:nil] objectAtIndex:0];        
   [cell retain];       // prevents zombies!
}
NSLog(@"%@: retainCount: %d", identifier, [cell retainCount]);

// some other cell init stuff

return cell;

注意[cell retain]; line - 当它在那里时,代码在游泳中运行。拿出来,崩溃。 NSLog始终报告retainCount为2,因此不需要。但如果我做这样的事情:

   if ([cell retainCount] < 1) { [cell retain]; }       // does not prevent zombies!

它不起作用。没有alloc / init,所以我根本不需要做自动释放或担心这一点,我一直以为cellForRowAtIndexPath会为我释放单元格。

当我不使用Instruments时,这是我从xcode获得的错误:

*** -[CALayer retain]: message sent to deallocated instance 0x4d8e930

即使它适用于[cell retain];对于分析(对我而言),它看起来像是泄漏,所以我想解决这个问题。有谁知道这里发生了什么?

1 个答案:

答案 0 :(得分:2)

不要调用retainCount

绝对保留计数没用。

([cell retainCount] < 1)不可能奏效; retainCount永远不会返回零。

(是的 - 在cellForRowAtIndexPath:加载一个笔尖现在受到框架的祝福.Coolio。)

然后,您的问题出在其他地方,因为该代码(没有保留)是正确的。

在常规事件循环流失之前,它仍然很可能是自动释放池流失。特别是某些地方的某些东西对细胞的弱引用不应该。

如果启动分配工具并打开保留/释放事件记录,则可以确切地看到保留/释放/自动释放对象的调用的位置。导致崩溃的事件具有明显的价值。

但是,在这种情况下,您可能错过了某处的保留/释放对。至少,这将是症状的解决方法。真正的问题可能是某种类型的UI转换发生,使得某些内容有效地过早收获,而您的应用程序的某些其他部分仍然依赖于它。添加一个保留/释放对,以便在该转换过程中保留单元的生命周期并不是一个真正的修复,因为可能存在其他依赖关系。