我迷茫了!这是那些仅在特定条件下才会发生的讨厌的错误之一,但我无法直接将条件和结果联系起来。
我的应用程序有一个分页 UIScrollView,其中每个页面的 View 都来自 MyViewController(UITableViewController 的子类)。为了最大限度地减少内存使用,我卸载了那些当前不可见的 Controller 。这是我的“清理”方法:
- (void) cleanViewControllers:(BOOL)all {
if (all) {
// called if some major changes occurred and ALL controllers need to be cleared
for (NSInteger i = 0; i < [viewControllers count]; i++)
[viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
}
else if ([viewControllers count] > 2) {
// called if only the nearest, no longer visible controller need to be cleared
NSInteger i = pageControl.currentPage - 2;
if (i > -1) [viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
i = pageControl.currentPage + 2;
if (i < [viewControllers count]) [viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
}
}
正是这一行导致应用程序崩溃:
viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
viewControllers 是一个包含 MyViewController 类型对象的 NSMutableArray。 MyViewController 没有自定义属性,其 dealloc 方法只包含 [super dealloc] 调用。
这是调试器显示的内容: alt text http://a.imageshack.us/img831/3610/screenshot20100806at126.png
问题是,这种情况不会在每次 Controller 被清除时发生,而只是有时发生。具体来说,在某些更改触发 ScrollView 的完全清理和重新绘制后,它可以很好地显示当前页面(称为 X),但是一旦我滚动得足够远以导致 X 的清理,就会发生此崩溃。这让我发疯!
另一件事,这种情况不会发生在 4.0 模拟器中,也不会发生在 iPad 上,但在运行 3.1.3 的第一代 iPod touch 上却非常一致地发生。
最佳答案
正在释放某些东西,但指针仍然悬空。将 NSZombieEnabled 设置为 YES 并再次运行。方法如下:
- 产品 -> 编辑方案
- 选择“参数”选项卡
- 添加到“要在环境中设置的变量”
- 名称:NSZombieEnabled
- 值:是
在 Xcode 4.1 及更高版本中:
- 产品 -> 编辑方案
- 选择“诊断”选项卡
- 您可以选择启用僵尸对象。
再次运行应用程序。在某些时候它会告诉您正在访问一个已经释放的对象。由此您需要弄清楚谁没有保留或谁过度释放了该对象。
快乐的僵尸狩猎。
关于iPhone EXC_BAD_ACCESS 在自定义 UIViewController 上调用 [super dealloc] 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3426709/