2011-08-25 195 views
2

我的應用程序在Lion上崩潰時,它從睡眠中醒來。 這個問題似乎與後臺線程正在尋找天氣信息。 我不知道,但我覺得崩潰日誌告訴我,自動釋放池彈出不再有對象,有人可以幫助我確認這一點?幫助崩潰日誌

這裏是崩潰日誌有關的詳情:

過程:對myApp [14187]標識符:對myApp版本:
??? (???)編碼類型:X86-64(母語)父進程:的launchd [224]

日期/時間:2011-08-24 18:58:00.581 -0400 OS版本:的Mac OS X 10.7 0.1(11B26)報告版本:9

崩潰螺紋:7

異常類型:EXC_BAD_ACCESS(SIGSEGV)異常代碼: KERN_INVALID_ADDRESS在0x0000000000000010

特定應用信息:objc [14187]:垃圾收集是 OFF

螺紋7毀損:0 libobjc.A.dylib
0x00007fff9321700b(匿名 命名空間):: AutoreleasePoolPage ::彈出(無效*)+ 385 1
com.apple.CoreFoundation 0x00007fff961306a5 CFAutoreleasePoolPop + 37 2 COM。 apple.Foundation
0x00007fff969350d7 - [NSAutoreleasePool漏極] + 154 3
com.piso13.opusDomini 0x00000001000acb91 - [天氣 internalStart] + 417 4 com.apple.Foundation
0x00007fff9698b1ea - [NSThread主] + 68 5 com.apple 。基礎
0x00007fff9698b162 NSThread
_main + 1575 6 libsystem_c.dylib
0x00007fff90b068bf _pthread_start + 335 7 libsystem_c.dylib
0x00007fff90b09b75 thread_start + 13

這裏是我的天氣內部啓動代碼:

-(void)internalStart{ 
    pool = [[NSAutoreleasePool alloc] init]; 

    forecast = FALSE; 
    liveweather = FALSE; 

    NSString *query = [self generateQuery]; 
    if (query == nil) { 
     [pool drain]; 
     return; 
    } 


    XmlWrapper * xmlWrapper = [[XmlWrapper alloc] initWithQuery:query delegate:self name:@"liveweather"]; 
    [xmlWrapper release]; 

    query = [self generateForecastQuery]; 
    xmlWrapper = [[XmlWrapper alloc] initWithQuery:query delegate:self name:@"forecast"]; 
    [xmlWrapper release]; 

    [pool drain]; 

} 

我是否應該打電話給[pool drain]?

+0

這裏沒有看起來錯......你可以展示一些'generateForecastQuery'或'generateQuery'嗎?或者,也許你的'XmlWrapper'類? – jtbandes

+0

你從哪裏複製了該崩潰日誌?這全是錯誤的。請將它從原始崩潰日誌文件複製到〜/ Library/Logs文件夾中,並編輯您的問題以包含帶有代碼格式的文本。 –

+2

創建它們時立即釋放您的XMLWrapper對象是一個紅旗。你爲什麼做這個? –

回答

4

創建綁定的壽命和明確範圍的自動釋放池。

在這種情況下

,你存儲在一個實例變量(假定)的自動釋放池。

只是使它本地的方法,像這樣:

- (void)internalStart 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    //... 
    [pool drain], pool = nil; 
} 

,其通常引入的問題是:

1)自動釋放池棧爲基礎(池壓入和彈出)。通過抓住它,你可以輕鬆搞定堆棧順序。2)如果此類在多線程上下文中運行,則當您從多個線程中推送和彈出池時,您可以輕鬆地泄漏池或銷燬堆棧順序。

3)也可能泄漏池在多線程環境

+3

更簡單:當這個方法在兩個不同的線程上運行時,每個線程將自己的自動釋放池放入'pool'實例變量中 - 但由於實例變量按照定義* per-instance *,兩個線程都將它們匯入同一個地方。只有一個勝利,然後兩個線程都試圖消耗同一個池。這是崩潰。 –

+0

彼得謝謝你這是崩潰....你能幫助我釋放過早嗎?這個xmlWrapper從互聯網上讀取信息,並在天氣信息準備就緒時向委託人(呼叫者)發送消息。處理過程中xmlWrapper可能會被銷燬嗎? –

3

不幸的是,autoreleasepool崩潰是一些最難調試的。從靜態分析器開始,它可以找到一些東西。然後打開NSZombies。你的XmlWrapper對象有點奇怪。爲什麼你一創建它就立即發佈它?這是圍繞NSURLConnection的包裝嗎?您仍然應該保持對象,以便在釋放此對象時可以取消它或清除它的委託。

確保您使用所有ivars的訪問器,而不是直接訪問它們。根據我的經驗,直接訪問initdealloc之外的ivars是導致這類崩潰的首要原因。

+0

從您的意見中,我想我可能會很快發佈xmlWrapper。 xmlwrapper將向代理(當前調用者)發送一條消息,表明信息已準備好閱讀。在發送完委託消息之前,是否可以在內部處理過程中釋放此對象? –