2013-02-15 78 views
0

我使用的是NSThread如下NSThread內存泄漏

NSThread * thread = [[NSThread alloc] initWithTarget:object selector:@selector(bg) object:nil]; 
[thread start]; 

後來我想停止線程和釋放對象,如下所示:

[thread cancel]; 
[object release]; 

這似乎是工作確定。然而,當我看到泄漏工具時,我看到一些神祕的泄漏不是來自我的代碼(一個空的NSArray)。當我查看malloc歷史記錄時,我發現NSArray被分配在最終從我的[object dealloc]中調用的「willChangeValueForKey」方法中。恰好是將委託設置爲零。該代表正在被觀察(因此willChangeValueForKey?)。從[NSThread出口]調用[object dealloc]。

我的猜測是,這是因爲[線程取消]不會立即停止線程(畢竟它是在不同的線程中)。然後我們在主線程上釋放對象。 這將其retainCount保留爲1.然後NSThread會在實際上停轉時釋放對象。看起來這會導致泄漏。我想這個快速變化來驗證我的假設:

[thread cancel]; 

[NSThread sleepForTimeInterval:1]; 
// This makes it wait until the thread releases [object] 

[object release]; 

問:爲什麼是不安全的,讓NSThread解除分配我的對象?它是否與dealloc中的觀察者代碼不安全有關?

+0

您的'willChange' /'didChange'是否在調用'addObserver:'和'removeObserver:'的相同線程上發生? – iluvcapra 2013-02-15 00:52:07

+0

你的線程是否有自己的autorelease池? – 2013-02-15 02:24:43

+0

autoreleasepool:是的。至於iluvcapra的問題:我不確定。這段代碼非常複雜,所以我不能100%確定。可以讓他們在不同的線程導致泄漏? – George 2013-02-15 08:59:06

回答

1

您的主線程應該立即可以[object release],您不必等到取消線程後,或者直到您啓動它爲止。 initWithTarget:隱含地保留objectcancel隱含地釋放它。

您不必在主線程上保留object以便爲分離的線程保持活動狀態。

+0

還有其他的原因,我需要保持'對象'周圍。但我也不確定這會有所幫助。當我從發佈的線程發佈發佈時,它看起來很混亂。 – George 2013-02-15 08:58:14

+0

我重構了一些內容,以使'object'不會阻塞太多東西,所以無論何時都可以安全地釋放它。我發現這個問題真的是'對象'被另一個觀察自己的對象所控制。根據一些研究,觀察自我似乎不是一個好的模式。所以這可能是這裏真正的解決方案,並且將是我最終做的。無論如何,分解NSThread特定的東西是合理的。謝謝您的幫助。 – George 2013-02-15 21:27:52

+0

我以前觀察過'self'並且它可以工作,但是跨越線程邊界的觀察效果很差。 – iluvcapra 2013-02-16 17:05:59