您好,登錄后才能下訂單哦!
觀察者設計模式
KVO也叫 “發布--訂閱”模式,很像雜志的訂閱。
讀者把名字和郵寄地址提供給發行商
發行商在發行新一期的的雜志時,就能將雜志送到每一個讀者手中
原理:
訂閱者注冊成為發布者的某一屬性的觀察者
當發布者的這一屬性發生變化時,所有的觀察者都會得知該屬性的變化
KVC(鍵值編碼)是實現KVO的基礎
與代理的功能類似,用來實現:對象間傳遞事件、數值,但不能為自身屬性賦值
觀察者設計的使用步驟
1)發布者添加屬性
如一個Person類,添加屬性age
@interface AMPerson : NSObject @property (nonatomic, strong) NSNumber* age; @end
2)注冊成為訂閱者
發布者調用addObserver:forKeyPath:options:context:方法,注冊其指定屬性的訂閱者
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
如控制器創建一個Person對象,并成為其訂閱者
self.person = [[AMPerson alloc] init]; self.person.age = @10; [self.person addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];
3)訂閱者實現observeValueForKeyPath:ofObject:change:context:方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
如:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { if ( [keyPath isEqualToString:@"age"] ) { NSLog(@"%@", change); } }
4)發布者的屬性發生變化時訂閱者會響應
響應方法即發布者的observeValueForKeyPath:ofObject:change:context:方法
注意:必須使用KVC的賦值方式訂閱者才會響應
如:
NSInteger age = self.person.age.integerValue+1; [self.person setValue:@(age) forKey:@"age"];
5)訂閱者銷毀前將注冊信息刪除
發布者使用removeObserver:forKeyPath:方法刪除指定的訂閱者
- (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath
如:
- (void)dealloc { [self.person removeObserver:self forKeyPath:@"age"]; }
通知機制
通知機制是基于觀察者設計模式實現一種對象間的通信技術。
雖然Objective-C的對象支持直接使用觀察者設計模式開發,但通知機制的使用過程更加簡單
通知中心是一種多對多的通信方式,而觀察者僅僅是一對多的通信方式
通知中心:
每個應用程序都有一個實現通知機制的實例,稱作通知中心(NSNotificationCenter)
獲得其單例對象:
+ (NSNotificationCenter *)defaultCenter
通知中心還包含添加、刪除通知關系的方法
通知的發布者:
任何對象都可以向通知中心發布消息
通知的接受者:(響應者)
任何對象都可以在通知中心注冊所關心的消息,并在關系消息被發布時收到
通知對象(NSNotification)主要包含以下三個屬性:
@property(readonly, copy) NSString *name //通知名 @property(readonly, retain) id object //通知的發布者 @property(readonly, copy) NSDictionary *userInfo //通知中可以攜帶的數據
通知的使用過程
1)起一個通知的名字
一般在發布者源文件中定義并在頭文件中聲明
//AMAppView.h extern NSString * const AMAppViewNameBtnClickedNotification; //AMAppView.m NSString * const AMAppViewNameBtnClickedNotification = @"AMAppViewNameBtnClickedNotification";
2)通知發布者通過通知中心發布通知
通知中心使用postNotification方法發布通知
- (void)postNotification:(NSNotification *)notification - (void)postNotificationName:(NSString *)notificationName object:(id)notificationSender - (void)postNotificationName:(NSString *)notificationName object:(id)notificationSender userInfo:(NSDictionary *)userInfo
如:
[[NSNotificationCenter defaultCenter] postNotificationName:AMAppViewNameBtnClickedNotification object:self userInfo:@{@"appModel":self.appModel}];
3)通知接收者通過通知中心注冊想要接收的通知
使用通知中心的addObserver方法
- (void)addObserver:(id)notificationObserver selector:(SEL)notificationSelectorname:(NSString *)notificationName object:(id)notificationSender - (id<NSObject>)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block
如:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appViewNameBtnClicked:) name:AMAppViewNameBtnClickedNotification object:v];
4)通知接收者實現通知的響應方法或block
- (void) appViewNameBtnClicked:(NSNotification*) notification { NSLog(@"%@", notification.name); NSLog(@"%@", notification.object); NSLog(@"%@", notification.userInfo); }
5)通知接收者在被銷毀或者不再想接收通知時,從通知中心移除
使用通知中心的removeObserver方法
- (void)removeObserver:(id)notificationObserver - (void)removeObserver:(id)notificationObserver name:(NSString *)notificationNameobject:(id)notificationSender
一般放在接受者的dealloc方法中調用,如:
- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
使用場景的區別:
代理設計模式:一對一的關系 對象間關系相對比較緊密
觀察者設計模式:一對多的關系
通知機制:多對多的關系
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。