子类化 UITableViewCell 会创建僵尸,除非保留
我创建了一个带有自定义笔尖的 UITableViewCell 子类,并在我的应用程序中的两个不同的 UITableView 中使用它。它在其中一个表中运行得很好,但当我用力滚动它时,另一个表崩溃了。 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 keep]; line - 当它在那里时,代码可以顺利运行。拿出来就崩溃了NSLog 总是报告保留计数为 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 keep];行,它看起来像是分析(和我)的泄漏,所以我想解决这个问题。有人知道这是怎么回事吗?
I've created a UITAbleViewCell subclass with a custom nib, and am using it in two different UITableViews in my app. It works perfectly in one of the tables, but the other table crashes when I scroll it vigorously. Instruments identifies a zombie in this code (in 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;
Notice the [cell retain]; line - when it's in there, the code works swimmingly. Take it out, and crash. NSLog always reports a retainCount of 2, so it shouldn't be necessary. But if I do something like this:
if ([cell retainCount] < 1) { [cell retain]; } // does not prevent zombies!
it doesn't work. There's no alloc/init, so I shouldn't have to do an autorelease or worry about this at all, and I've always thought that cellForRowAtIndexPath releases the cell for me.
When I'm not using Instruments, here's the error I get from xcode:
*** -[CALayer retain]: message sent to deallocated instance 0x4d8e930
Even though it works with the [cell retain]; line, it looks like a leak to Analyze (and to me), so I'd like to resolve the problem. Anyone know what's going on here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要调用retainCount
绝对保留计数是没有用的。
([cell keepCount] < 1)
不可能工作;retainCount
永远不能返回零。(是的 - 在
cellForRowAtIndexPath:
中加载笔尖现在受到框架的祝福。Coolio。)那么,您的问题出在其他地方,因为该代码(没有保留)是正确的。
它仍然很可能是在常规事件循环耗尽之前发生的自动释放池耗尽。特别是,某些地方对单元格的引用不应该有弱引用。
如果您启动分配工具并打开保留/释放事件记录,您可以准确地看到对保留/释放/自动释放对象的调用发生的位置。导致崩溃的事件具有明显的价值。
但在这种情况下,您可能在某处缺少保留/释放对。至少,这可以解决症状。真正的问题可能是发生某种 UI 转换,导致某些内容实际上过早地被收获,而应用程序的其他部分仍然依赖于它。添加保留/释放对,以便在整个转换过程中保留单元的生命周期,这并不是真正的解决方案,因为可能存在其他依赖项。
Do not call retainCount
The absolute retain count is useless.
([cell retainCount] < 1)
cannot possibly work;retainCount
can never return zero.(Yup -- loading a nib in
cellForRowAtIndexPath:
is now blessed by the framework. Coolio.)Your problem, then, lies elsewhere as that code (without the retain) is correct.
It is still quite likely to be an autorelease pool drain that is happening before the regular event loop drain. In particular, something somewhere has a weak reference to the cell that shouldn't.
If you fire up the Allocations Instrument and turn on retain/release event recording, you can see exactly where the calls to retain/release/autorelease the object occur. The event that causes the crash is of obvious value.
In this case, though, you are probably missing a retain/release pair somewhere. At least, that would be a fix for the symptoms. The real problem is likely some kind of UI transition that happens such that some contents are effectively prematurely reaped while some other section of your app still has dependencies on it. Adding a retain/release pair such that the lifespan of the cell is preserved across that transition isn't really a fix in that there may be other dependencies.