最近app中加了很多通知,但誤用通知會(huì)導(dǎo)致方法多次調(diào)用等各種問(wèn)題,為了研究透通知的處理機(jī)制,舉了幾個(gè)例子來(lái)講解。
為了深入了解通知的處理機(jī)制,首先我們要明白控制器的生命周期(調(diào)用先后順序如下):
載入完成,可以進(jìn)行自定義數(shù)據(jù)以及動(dòng)態(tài)的創(chuàng)建其他空間:
- (void)viewDidLoad
視圖將出現(xiàn)在屏幕之前: - (void)viewWillAppear:(BOOL)animated
視圖在屏幕上渲染完成: - (void)viewDidAppear:(BOOL)animated
視圖被移除之前 - (void)viewWillDisappear:(BOOL)animated
視圖被移除完成 - (void)viewDisappear:(BOOL)animated
銷(xiāo)毀視圖 - (void)dealloc
值得注意的是:
-(void)viewDidLoad 只會(huì)在控制器初始化時(shí)載入一次,
-(void)dealloc也只會(huì)在控制器銷(xiāo)毀時(shí)載入一次.
而其他四個(gè)方法可以根據(jù)多個(gè)視圖控制器切換時(shí)多次調(diào)用.
所以通知的業(yè)務(wù)邏輯可以根據(jù)以上進(jìn)行合理的調(diào)度。
關(guān)于通知的注冊(cè)和移除
有人喜歡方法一:
- (void)viewWillAppear:(BOOL)animated注冊(cè)通知
- (void)viewWillDisappear:(BOOL)animated移除通知
也有人喜歡方法二 - (void)viewDidLoad 注冊(cè)通知,
- (void)dealloc移除通知.
其實(shí)這都是需要根據(jù)業(yè)務(wù)邏輯來(lái)處理的,并不能一概而論。
例如:
在大廳中監(jiān)聽(tīng)房間的創(chuàng)建和銷(xiāo)毀,可以初始化時(shí)就開(kāi)啟監(jiān)聽(tīng),作為最底層的控制器即可選擇方法二。
而在一些權(quán)限界面,比如玩家達(dá)成一定條件才開(kāi)啟的,可以采用方法一。
甚至可以不局限于這些地方,只要方法適當(dāng)可以在任何地方注冊(cè)和銷(xiāo)毀,當(dāng)然注冊(cè)了通知后,移除對(duì)應(yīng)的通知也是必要的。
還有一些問(wèn)題:
當(dāng)在某個(gè)控制器不小心一次性注冊(cè)幾次通知:
-(void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(father)
name:@"father"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(father)
name:@"father"
object:nil];
}
你就可能會(huì)接收到同樣多的信息:
2017-08-22 15:30:32.060 MyFrameWork[10504:299552] father
2017-08-22 15:30:33.172 MyFrameWork[10504:299552] father
但是移除通知只需要移除一次即可:
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"father" object:nil];
另一方面,如果基類里面注冊(cè)了通知,最好選擇在基類的
-(void)viewDidLoad中注冊(cè)。
其實(shí)會(huì)用通知后,開(kāi)發(fā)就很方便了,特別是用于基于sokect的編程中,不斷地和服務(wù)器進(jìn)行交互,需要分發(fā)好服務(wù)器推送過(guò)來(lái)的信息,不然就可能造成信息錯(cuò)亂,內(nèi)存異常等問(wèn)題。