2009-08-08 38 views
0
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) 

目前我的程序中有一个非常奇怪的错误。有时会发生,有时并不会。但这里是发生了什么事情的总结:有人可以给我一个关于这个stacktrace在iPhone应用程序中的手吗?

当程序启动:

  • 保存的数据(仅短短的plist由13种元素),如果存在被加载。
  • 包含1014个字符串的巨大plist被加载到NSMutableDictionary中。
  • 另一个包含78个字符串的plist被加载到一个NSArray中。
  • 播放.mp4影片。

该错误发生在OpenGL ES View被删除并且用户将要查看NSMutableDictionary中1014个字符串中的一个字符串的部分。

模拟器中不会出现此错误。它只发生在iPhone上,有时它运行良好,但有时它会崩溃。

但是,在阅读堆栈跟踪之后,我在那里看到了CFDictionaryApplyFunction,所以我认为这可能是其中一个可能的原因。是因为在模拟器上,它读取的东西太快,以至于来自plist的整个字典都会立即加载,而在设备上,它读取速度较慢?老实说,我不知道字典是如何工作的。它是否会立即读取所有1014个字符串,或者是否使用其他线程缓慢读取?请指教。谢谢。

+2

在iPhone上,内存相对较小,因此您更有可能获得内存警告。在模拟器上,尝试模拟内存警告(在硬件菜单项下找到选项)。 – notnoop 2009-08-08 13:52:51

回答

5

当你得到一个EXC_BAD_ACCESS时,它通常意味着你试图调用一个不存在的对象的方法 - 可能是因为它已被释放。

大约一半下来的痕迹,也有一些内存警告调用,如:

#12 0x30a00710 in -[UIApplication _performMemoryWarning]() 

这使得它似乎不关你的代码是直接导致崩溃,而是一个系统内存不足时发出通知。

接近帧#0,它似乎试图清除对象的缓存,并且这看起来是不好的访问。

基于此,有一种猜测是您将指针指向便捷构造函数的自动释放返回值;那么该对象是自动释放的,并且您可能认为没有问题,因为您不直接使用该映像,但内存警告尝试访问它。例如:

@interface MyClass { 
    UIImage* myImage; 
} 
// ... 
- (id) init { /* the usual stuff */ 
    myImage = [UIImage imageNamed:@"bob_the.png"]; 
    return self; 
} 

在这个例子中,即使你有一个保留属性设置上myImage,您实际上并不保持图像,除非你通过self.myImage设置的值。所以,在这次电话会议后不久,图像就被释放出来,并且你已经有了一个指向无人地带的指针。

没有看到代码,我无法知道这是否是实际发生的事情,但这是一种容易犯的错误。

这些相关问题给出类似的崩溃提示:EXC_BAD_ACCESS调试question 1question 2

最后,如果没有任何帮助,我建议您找到最小复制您的问题。要做到这一点的难办法是复制代码,剪掉一半,查看错误是否仍然存在,然后重复,直到找到能够找到错误的最小代码。从那里调试通常要容易得多(并且更容易作为一个stackoverflow问题!)如果你知道简单的方法,请告诉我。

+0

你也可以像这样分配它:'myImage = [[UIImage imageNamed:@“bob_the.png”] retain]'。 – notnoop 2009-08-08 13:54:09

+0

根据你所说的,也许这部分是麻烦的原因?以下代码位于UIImageView的子类的方法中。 NSString * st; st = [[NSString alloc] initWithFormat:@“sc%d.png”,chosenNumber]; self.image = [UIImage imageNamed:st]; [st release]; 基本上我设置了像这样的UIImageView的图像。这可能是原因吗? – Karl 2009-08-08 14:06:25

+0

允许我再测试一下,看看它是否会导致更多的错误。现在,我的UIImageView子类中保留了UIImage *。泰勒先生,非常感谢。 (作为学生鞠躬) – Karl 2009-08-08 14:39:44

1

您可能需要设置NSZombiesEnabled环境变量。这样,当访问发布的对象时,您的应用不会与EXC_BAD_ACCESS一起崩溃,而是会将一条提示信息记录到您的控制台。 This blog post很好地解释了会发生什么,以及如何在XCode中进行设置。无论如何,永远不要忘记在生产版本中禁用此选项,否则您的对象将永远不会被释放!

相关问题