2010-09-08 94 views
2

我在iPhone上運行一些小代碼的時間很糟糕。iphone:線程+發佈池+ [object release] =「發送到釋放實例的消息」

基本上,我只是按下一個按鈕,它調用runTest,它在後臺線程上運行test方法。這就是爲什麼我創建了一個自動釋放池。

如果我運行下面的代碼我得到了控制檯上一個美麗的消息說:
2010-09-07 11:45:15.527 test[1312:207] *** -[CFString release]: message sent to deallocated instance 0x3d52ba0

-(void) test { 
    NSAutoreleasePool *apool = [[NSAutoreleasePool alloc] init]; 

    NSString *xml = [[NSString alloc] initWithFormat:@"<%@>", @"msg"]; 
    NSLog(@"%@\n",xml); 
    [xml release]; 

    [apool release]; // <-- this line throws the error msg 
} 

- (IBAction) runTest: (id)sender 
{ 
    [self performSelectorInBackground:@selector(test) withObject:nil]; 

} 

我發現:如果我不運行在後臺線程test(無自動釋放池) ,只需撥打[self test],代碼工作正常。

所以,我認爲問題是圍繞線程+ autorelease池,我做錯了什麼?我該如何解決它?

P.S.我已啓用NSZombie標誌。

+0

我用上面給出的確切代碼創建了一個簡單的測試用例應用程序,它可以正常工作,並且沒有錯誤。更可能有一些你省略的代碼是罪魁禍首。 – 2010-09-08 18:18:16

+0

快速問題:爲什麼你需要這裏的autorelease池? – jrtc27 2010-09-08 18:45:47

+0

使用Cocoa或iOS Objective-C API時,您總是需要一個自動釋放池。在自己進行線程化時,您必須手動管理池。 – bbum 2010-09-08 19:52:14

回答

0

NSLog可能需要向UI線程發送一條消息(在主線程上執行選擇器)以便序列化到控制檯,屆時,xml已經發布。

+0

有趣,我刪除:'NSLog(@「%@ \ n」,xml);'問題依然存在 ' – jhon 2010-09-08 17:44:38

+0

好猜,但錯誤 - NSLog在任何被調用的線程上執行它的事情。 – bbum 2010-09-08 17:58:57

0

它在這種情況下應該沒有關係,但你應該永遠drain池,從來沒有release他們。

這是一個真正奇怪的錯誤,如果這是所有的代碼。

我建議的第一件事是在啓用殭屍檢測的同時運行代碼,同時在樂器中記錄所有保留/釋放事件。這會給你一個保留/釋放違規對象的清單。發佈結果,如果它仍然沒有意義。

0

您是否嘗試過使用-autorelease而不是對象xml?這會將其添加到活動池apool。聲明drain比聲明-release更好 - 它們在非垃圾收集環境中是相同的,但有一天Apple可能會在iPhone上實現垃圾收集。希望這可以幫助。

相關問題