Program received signal: “EXC_BAD_ACCESS”.
(gdb) bt
#0 0x30011940 in objc_msgSend ()
#1 0x30235f24 in CFRelease ()
#2 0x308f497c in -[UIImage dealloc] ()
#3 0x30236b78 in -[NSObject release] ()
#4 0x30a002a0 in FlushNamedImage ()
#5 0x30250a26 in CFDictionaryApplyFunction ()
#6 0x30a001a4 in _UISharedImageFlushAll ()
#7 0x30a00738 in +[UIImage(UIImageInternal) _flushCacheOnMemoryWarning:] ()
#8 0x3054dc80 in _nsnote_callback ()
#9 0x3024ea58 in _CFXNotificationPostNotification ()
#10 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#11 0x3054dbc0 in -[NSNotificationCenter postNotificationName:object:] ()
#12 0x30a00710 in -[UIApplication _performMemoryWarning] ()
#13 0x30a006a8 in -[UIApplication _receivedMemoryNotification] ()
#14 0x30a005d8 in _memoryStatusChanged ()
#15 0x30217416 in __CFNotificationCenterDarwinCallBack ()
#16 0x3020d0b0 in __CFMachPortPerform ()
#17 0x30254a76 in CFRunLoopRunSpecific ()
#18 0x3025416a in CFRunLoopRunInMode ()
#19 0x320452a4 in GSEventRunModal ()
#20 0x308f037c in -[UIApplication _run] ()
#21 0x308eea94 in UIApplicationMain ()
#22 0x00002096 in main (argc=1, argv=0x2ffff514)
目前我的程序中有一个非常奇怪的错误。有时它会发生,有时它不会发生。但这里是对正在发生的事情的总结:
程序启动时:
错误发生在删除OpenGL ES View并且用户即将查看NSMutableDictionary中1014个字符串的其中一个字符串的部分。
此错误在模拟器中永远不会发生。它只发生在iPhone上,有时它运行良好,但有时会破碎。
然而,在阅读了堆栈跟踪之后,我在那里看到了CFDictionaryApplyFunction,所以我认为这可能是其中一个可能的原因。是因为在模拟器上,它读取的内容如此之快,以至于plist中的整个字典会立即加载,而在设备上,它读取的速度较慢?老实说,我不确切知道字典是如何工作的。它是在瞬间读取所有1014个字符串,还是使用其他一些线程来慢慢读取?请指教。谢谢。
答案 0 :(得分:5)
当你得到一个EXC_BAD_ACCESS
时,它通常意味着你试图在一个不存在的对象上调用一个方法 - 可能是因为它被解除分配。
在跟踪的大约一半处,有一些内存警告调用,例如:
#12 0x30a00710 in -[UIApplication _performMemoryWarning] ()
这使得您的代码似乎没有直接导致崩溃,而是当内存不足时系统通知。
更接近第0帧,它似乎试图清除UIImage
对象的缓存,这似乎是错误访问。
基于此,一个猜测就是你要指定一个方便构造函数的自动释放返回值的指针;然后该对象是自动释放的,您可能认为这很好,因为您不直接使用该图像,但内存警告会尝试访问它。例如:
@interface MyClass {
UIImage* myImage;
}
// ...
- (id) init { /* the usual stuff */
myImage = [UIImage imageNamed:@"bob_the.png"];
return self;
}
在此示例中,即使您在myImage
上设置了保留属性,除非您通过self.myImage
设置值,否则实际上不会保留图像。因此,在此调用后不久,图像被释放,并且您有一个指向无人区域的指针。
如果没有看到代码,我无法知道这是否真的发生了,但这是一种容易犯的错误。
这些相关问题提供了类似崩溃的提示: EXC_BAD_ACCESS
调试 question 1和question 2。
最后,如果没有任何帮助,我建议您找到问题的最小再现。执行此操作的难点是复制代码,剪切一半,查看错误是否仍然存在,然后重复,直到获得可以找到的最小代码来重现错误。从那里进行调试通常要容易得多(而且作为stackoverflow问题也更容易出现!)如果你知道简单的方法,请告诉我。
答案 1 :(得分:1)
您可能想要设置NSZombiesEnabled
环境变量。这样,在访问已发布的对象时,您的应用程序不会因EXC_BAD_ACCESS
而崩溃,而是会向控制台记录信息性消息。 This blog post很好地解释了发生了什么以及如何在XCode中进行设置。无论如何,永远不要忘记在生产版本中禁用此选项,否则您的对象永远不会被释放!