iOS 通知 觀察者移除注意點(diǎn)?。?!

從 iOS 9 開始,即使不移除觀察者對(duì)象,程序也不會(huì)出現(xiàn)異常。

對(duì)于addObserver:要分ViewController和普通NSObject兩個(gè)說起

ViewController:在調(diào)用ViewController的dealloc的時(shí)候,系統(tǒng)會(huì)調(diào)用[[NSNotificationCenter defaultCenter]removeObserver:self]方法,所以如果是在viewDidLoad中使用addObserver添加監(jiān)聽者的話可以省掉移除。

普通NSObject:在iOS9之后,NSObject也會(huì)像ViewController一樣在dealloc時(shí)調(diào)用[[NSNotificationCenter

defaultCenter]removeObserver:self]方法,在iOS9之前的不會(huì)調(diào)用,需要自己寫。

但是在使用類別的時(shí)候如果我們添加了通知,那么我們是沒有辦法在類別里面重寫dealloc的,如果不移除通知就會(huì)出現(xiàn)野指針,這個(gè)時(shí)候我們就可以在iOS9以上使用addObserver,將通知的移除交給系統(tǒng),iOS9一下使用addObserverForName+weakSelf,雖然通知依然存在,但是不會(huì)調(diào)用doSomeThing方法(不要直接在block里面寫處理過程?。?。

為什么 iOS 9 之前需要手動(dòng)移除觀察者對(duì)象?

觀察者注冊(cè)時(shí),通知中心并不會(huì)對(duì)觀察者對(duì)象做 retain 操作,而是對(duì)觀察者對(duì)象進(jìn)行unsafe_unretained 引用。

什么是unsafe_unretained?因?yàn)?Cocoa 和 Cocoa Touch 中的一些類仍然還沒有支持 weak 引用。所以,當(dāng)我們想對(duì)這些類使用弱引用的時(shí)候,只能用unsafe_unretained來替代。

// for attribute

@property (unsafe_unretained) NSObject *unsafeProperty;

// for variables

NSObject *__unsafe_unretained unsafeReference;

不安全引用(unsafe reference)和弱引用 (weak reference) 類似,它并不會(huì)讓被引用的對(duì)象保持存活,但是和弱引用不同的是,當(dāng)被引用的對(duì)象釋放的時(shí),不安全引用并不會(huì)自動(dòng)被置為 nil,這就意味著它變成了野指針,而對(duì)野指針發(fā)送消息會(huì)導(dǎo)致程序崩潰。

因此,觀察者對(duì)象在釋放之前必須從通知中心移除引用,否則通知中心就會(huì)給野指針?biāo)玫膶?duì)象發(fā)送消息,導(dǎo)致程序崩潰。既然如此,為什么通知中心不對(duì)觀察者對(duì)象進(jìn)行弱引用呢?我們剛才已經(jīng)提到,Cocoa 和 Cocoa Touch 中的一些類還沒有支持弱引用,所以采用不安全的引用只是為了兼容舊的版本。

從 iOS 9 開始通知中心會(huì)對(duì)觀察者進(jìn)行弱引用,所以不需要在觀察者對(duì)象釋放之前從通知中心移除。但是,通過-[NSNotificationCenter addObserverForName:object:queue:usingBlock]方法注冊(cè)的觀察者依然需要手動(dòng)的釋放,因?yàn)橥ㄖ行膶?duì)它們持有的是強(qiáng)引用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容