Ios 禁用僵尸会导致EXC\u访问错误
我在应用程序中遇到以下堆栈跟踪崩溃-Ios 禁用僵尸会导致EXC\u访问错误,ios,objective-c,core-data,instruments,nszombieenabled,Ios,Objective C,Core Data,Instruments,Nszombieenabled,我在应用程序中遇到以下堆栈跟踪崩溃- Thread : Crashed: com.apple.main-thread 0 libobjc.A.dylib 0x39dfa66a objc_release + 9 1 libobjc.A.dylib 0x39dfb0d7 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 358 2 CoreFoundation
Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x39dfa66a objc_release + 9
1 libobjc.A.dylib 0x39dfb0d7 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 358
2 CoreFoundation 0x2f4a6c69 _CFAutoreleasePoolPop + 16
3 CoreFoundation 0x2f53c1cb __CFRunLoopRun + 1306
4 CoreFoundation 0x2f4a6f0f CFRunLoopRunSpecific + 522
5 CoreFoundation 0x2f4a6cf3 CFRunLoopRunInMode + 106
6 GraphicsServices 0x343ff663 GSEventRunModal + 138
7 UIKit 0x31df216d UIApplicationMain + 1136
8 Batted 0x0009db07 main (main.m:16)
当方案的诊断选项中未启用僵尸时,会发生崩溃。但是,当我启用它时,崩溃没有发生
我已经阅读了一些关于这方面的其他问答,他们似乎都建议,一旦看到这种行为,启用僵尸并在模拟器上运行僵尸配置文件工具
我试过了,但仪器似乎没有显示出任何错误,应用程序也能正常工作。
有什么线索可以说明还有什么办法可以从根本上解决这个问题?
我正在模拟器中使用XCode 5.1和iOS 7.1
更新1
发现了导致问题的违规代码,但我仍然不确定它导致问题的原因。
我使用的是CoreData,在NSManagedObject的子类中,我有-
- (void)willTurnIntoFault;
{
[super willTurnIntoFault];
if ([self observationInfo])
{
BNLogInfo(@"%@ has observers:\n%@", [self objectID], [self observationInfo]);
}
}
在上面的代码中,[self observationInfo]
是有问题的行
当应用程序启动时,我循环遍历枚举块中的一些NSManagedObject,并在其上设置一些属性,从而触发willTurnIntoFault
方法。一旦枚举块完成,就会发生崩溃
神秘的是,崩溃不会发生在这个方法内部,但如果没有这个方法子类,一切都会正常运行。Q&a说启用僵尸(或在僵尸工具下运行),因为僵尸经常导致这种错误 但这不是唯一的原因 你的程序正在破坏堆。很可能它正在覆盖自动释放池中某个对象中的
isa
指针(类指针),因此当运行循环耗尽自动释放池时,objc\u release
尝试取消对伪isa
指针的引用并崩溃
启用僵尸可以掩盖这样的错误,因为对于僵尸,运行时实际上从未释放对象。这意味着堆中有很多部分无法使用(除非您尝试向僵尸发送消息),因此,如果您损坏它们,它们永远不会造成麻烦
这些类型的崩溃可能很难调试,但有一个叫做“guard malloc”的工具有时会有所帮助。从菜单栏中,选择产品>方案>编辑方案。单击左侧列表中的运行操作。然后单击诊断选项卡。启用“启用保护Malloc”选项。然后试着复制崩溃。Guard malloc将立即检测到某些类型的堆损坏,并根据损坏指令停止程序。该应用程序在启用僵尸的情况下工作,因为当它启用时,实际上不会释放任何对象。但是您应该在调试控制台中看到当您引用解除分配的对象时指出的消息。这就是启用僵尸的全部意义。然后,您尝试确定访问过度释放对象的原因。当您启用僵尸时,您将在调用解除分配对象上的方法时收到通知。检查该对象并查找该对象被解除分配的所有位置。崩溃前调试控制台中是否有任何警告?崩溃前没有任何消息或警告。也没有对解除分配对象的引用。m:16号线,没有提供任何信息。启用僵尸后,不会出现崩溃或任何错误迹象。我尝试了
guard malloc
,但它没有提供任何额外信息。其行为与之前相同(即,有僵尸时不会崩溃,如果没有启用僵尸,则崩溃时不会有额外信息)