KVO與通知都可實(shí)現(xiàn)觀察者模式蜀踏。
一妹沙、通知簡介
NSNotificationCenter是一個(gè)消息通知機(jī)制揩魂,類似廣播。觀察者只需要向消息中心注冊(cè)消息拐揭,當(dāng)有地方發(fā)出這個(gè)消息的時(shí)候撤蟆,通知中心會(huì)發(fā)送給注冊(cè)這個(gè)消息的對(duì)象。消息發(fā)送者和消息接受者兩者可以互相一無所知堂污,完全解耦家肯。
觀察者向消息中心注冊(cè)以后,在不需要接受消息時(shí)需要向消息中心注銷盟猖,屬于典型的觀察者模式讨衣。
消息通知中重要的兩個(gè)類:
(1) NSNotificationCenter: 實(shí)現(xiàn)NSNotificationCenter的原理是一個(gè)觀察者模式,獲得NSNotificationCenter的方法只有一種扒披,那就是[NSNotificationCenter defaultCenter] 值依,通過調(diào)用靜態(tài)方法defaultCenter就可以獲取這個(gè)通知中心的對(duì)象了。NSNotificationCenter是一個(gè)單例模式碟案,而這個(gè)通知中心的對(duì)象會(huì)一直存在于一個(gè)應(yīng)用的生命周期愿险。
(2) NSNotification: 這是消息攜帶的載體,通過它价说,可以把消息內(nèi)容傳遞給觀察者辆亏。
二、通知的使用
1鳖目、在當(dāng)前控制器發(fā)送通知接收通知
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1.注冊(cè)通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(firstNotificationFunc:) name:@"First" object:nil];
}
//2.通知回調(diào)方法
- (void)firstNotificationFunc:(NSNotification *)notification{
NSString *name = [notification name];
NSLog(@"打印%@",name);
}
//3.銷毀
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
//4.發(fā)送通知
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[[NSNotificationCenter defaultCenter] postNotificationName:@"First" object:self];
}
@end
注意:只有注冊(cè)通知之后才可以接收發(fā)送的通知扮叨。
通知可傳遞參數(shù),userInfo领迈、object彻磁。
2、在push的下一界面發(fā)送通知狸捅,在上一控制器接收通知
//第一個(gè)控制器
#import "ViewController.h"
#import "NextViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"第一個(gè)控制器";
//1.注冊(cè)通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(firstNotificationFunc:) name:@"First" object:nil];
}
//2.通知回調(diào)方法
- (void)firstNotificationFunc:(NSNotification *)notification{
NSString *name = [notification name];
NSLog(@"打印%@%@",self.title,name);
}
//3.銷毀
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
NSLog(@"銷毀");
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//跳轉(zhuǎn)
NextViewController *vc = [[NextViewController alloc]init];
[self.navigationController pushViewController:vc animated:YES];
}
@end
**********************************************************
//第二個(gè)控制器
#import "NextViewController.h"
@interface NextViewController ()
@end
@implementation NextViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = @"第二個(gè)控制器";
self.view.backgroundColor = [UIColor whiteColor];
}
//發(fā)送通知
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[[NSNotificationCenter defaultCenter] postNotificationName:@"First" object:nil];
}
@end
//也可以根據(jù)通知名移除注冊(cè)的通知
- (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;
三衷蜓、通知的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 不需要編寫多少代碼,實(shí)現(xiàn)比較簡單尘喝。
- 對(duì)于一個(gè)發(fā)出的通知磁浇,多個(gè)對(duì)象能夠做出反應(yīng),即一對(duì)多的消息通知機(jī)制朽褪。
- 可以傳遞參數(shù)置吓,userInfo无虚, object。
缺點(diǎn):
- 在編譯器不會(huì)檢查通知是否能夠被觀察者正確的處理衍锚;
- 注冊(cè)的觀察者友题,一定要移除。
- 只有注冊(cè)了通知构拳,才能接收通知消息咆爽。注冊(cè)通知對(duì)象要在發(fā)送通知的前面才可接收到通知。
- 通知發(fā)出后置森,controller不能從觀察者獲得任何的反饋信息斗埂。