2009-08-08 21 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中進行設置。無論如何,永遠不要忘記在生產版本中禁用此選項,否則您的對象將永遠不會被釋放!

相關問題