3

我的主要程序產生一個線程,它執行以下操作:Objective-C的NSThread裁判計數約定(保留VS自動釋放)

// alloc autorelease pool somewhere before 
NSArray *blah = [NSArray arrayWithObject: @"moo"]; 
[self performSelectorOnMainThread: @selector(boonk:) withObject: blah 
     waitUntilDone: NO]; 
// release autorelease pool somewhere after 

現在,這似乎是車對我來說,因爲自動釋放池會前發佈選擇器boonk:完成執行,這會導致崩潰。

所以,我自然的下一步行動將是:

// alloc autorelease pool somewhere before 
NSArray *blah = [[NSArray alloc] initWithObject: @"moo"]; 
[self performSelectorOnMainThread: @selector(boonk:) withObject: blah 
     waitUntilDone: NO]; 
// release autorelease pool somewhere after 


- (void)boonk: (id)data 
{ 
    // do something with data 
    [data release]; // release the ref count the thread added 
} 

這絕對是無bug,但似乎....不自然。是否有一個Objective-c計數約定或協議來處理這種情況(跨線程無等待發布),還是第二個解決方案超出了它的做法?

回答

9

實際上,performSelectorOnMainThread保留其參數直到之後執行選擇器,因此不需要這樣做。

+0

那麼,我會加快,就是這樣。他們在方法描述結束時將其隱藏在一個小小的便箋中。太棒了,謝謝! – MarcWan 2010-01-11 11:13:46

+0

嗯,我只記得*直到選擇器被執行*,而不是*之後* :) – 2010-01-11 11:15:52

+0

嗯,在執行選擇器之後不會釋放參數(NSArray等等)嗎?框架保留論點的全部目的是讓你免於保留和釋放它,並確保你不會忘記保留它導致崩潰。自動釋放池在這裏超出範圍,因爲編碼器不保留參數,但是框架在必要時保留並釋放它。 – Costique 2010-01-11 11:19:54

3

規則很簡單;要將線程A中的對象傳遞給線程B,必須存在硬保留。現在,如記錄,-performSelectorOnMainThread:(和變體)保留的對象,直到方法完成執行,無論同步或異步調用。

但是,通常是保持發送線程保留髮送線程的主題。這是明確的意圖,並將支持未來的重構,潛在的其他模型,而不是做自動保留/釋放。

而且,要重複一次,因爲它很重要,autorelease池不能用於跨線程保留對象。