即使在方法調用正在進行時(
link)
*,對象可能會被釋放,對於註冊並接收將在不同線程上傳遞的通知的安全從它預期將被釋放的那個?NSNotificationCenter和安全多線程
作爲參考,documentation指出
在多線程應用程序,通知始終在該通知被張貼線程,這可能不是由觀察者本身註冊在同一個線程交付。
同樣重要的是,NSNotificationCenter不保留對已註冊接收通知的對象的強引用。
下面是一個例子,這可能使局勢更加具體:
- (id)init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:SomeNotification object:nil];
}
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)handleNotification:(NSNotification *)notification {
// do something
}
與此實施的對象上接收線程X. SomeNotification之前-handleNotification:回報,最後強大的參考對象(代碼我可以看到)壞了。
我是在想,糾正:
一個。如果NSNotificationCenter在調用-handleNotification之前對該對象進行強引用,那麼該對象將不會被釋放,直到after -handleNotification:返回,並且
b。就可以了,那麼對象可-handleNotification之前釋放:如果NSNotificationCenter不調用-handleNotification之前採取強有力的參考對象返回
哪種方式(A或B),它的工作原理?我還沒有在文檔中發現該主題,但在多線程環境中安全使用NSNotificationCenter似乎有點重要。
UPDATE:在上述環節的答案被更新表示「ARC保留並圍繞弱引用調用釋放」。這意味着在方法調用正在進行時不應該釋放對象。
感謝您的回答。這種方法確實解決了導致我的問題的問題。我仍想知道,在我提出的例子中,NSNotificationCenter在調用它註冊的方法時保留了觀察者。 –
我沒有看到任何承諾的文檔。你可以嘗試通過使dealloc非常慢(例如使用sleep())並添加printf()日誌來探索它。 (絕對不要使用NSLog進行線程分析。)但是我懷疑你可以依賴於結果。即使ARC承諾它,你也不知道NSNotificationCenter是否在內部使用ARC。唯一真正的承諾是你從文檔中獲得的。 –
感謝您的編輯;我已經在真正的代碼中搞砸了...... –