在前一篇文章中咱們介紹了OC中很經常使用的兩個技術:KVC和KVO: http://blog.csdn.net/jiangwei0910410003/article/details/41912937,今天咱們來看一下OC中另外的一個經常使用技術:通知(Nofitication)java
其實這裏的通知和以前說到的KVO功能很想,也是用於監聽操做的,可是和KVO不一樣的是,KVO只用來監聽屬性值的變化,這個發送監聽的操做是系統控制的,咱們控制不了,咱們只能控制監聽操做,相似於Android中系統發送的廣播,咱們只能接受。可是通知就不同了,他的監聽發送也是又咱們本身控制,咱們能夠在任何地方任什麼時候機發送一個通知,相似於Android中開發者本身發送的廣播。從這一點看來,通知的使用場景更爲普遍了。app
下面就來看一下例子:post
仍是護士和小孩的那個例子spa
Children.h.net
// // Children.h // 44_KVO // // Created by jiangwei on 14-10-16. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import <Foundation/Foundation.h> @interface Children : NSObject @property NSInteger *hapyValue; @end定義了一個屬性:hapyValue
Children.mcode
// // Children.m // 44_KVO // // Created by jiangwei on 14-10-16. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import "Children.h" @implementation Children - (id) init{ self = [super init]; if(self != nil){ //啓動定時器 [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES]; self.hapyValue= 100; } return self; } - (void) timerAction:(NSTimer *) timer{ //使用set方法修改屬性值,才能觸發KVO _hapyValue--; NSLog(@"%@",_hapyValue); if(_hapyValue <80){ //發送通知 //這裏和KVO的區別,咱們能夠手動的發送通知 //注意通知的名稱,傳遞的參數必須和定義通知的地方的參數值要一致 //將Children對象傳遞過去 [[NSNotificationCenter defaultCenter] postNotificationName:@"happyValueNotification" object:self]; } } @end定義了一個定時器,可是咱們看到這裏的timerAction方法中就開始發送一個通知了:
//發送通知 //這裏和KVO的區別,咱們能夠手動的發送通知 //注意通知的名稱,傳遞的參數必須和定義通知的地方的參數值要一致 //將Children對象傳遞過去 [[NSNotificationCenter defaultCenter] postNotificationName:@"happyValueNotification" object:self];咱們在屬性值發生變化的地方發送一個通知:NSNotificationCenter
第一個參數:通知的名稱,這個名稱必須和後面接受通知的名稱一致server
第二個參數:能夠傳遞的一個參數對象對象
Nure.hblog
// // Nure.h // 44_KVO // // Created by jiangwei on 14-10-16. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import <Foundation/Foundation.h> @interface Nure : NSObject @end
// // Nure.m // 44_KVO // // Created by jiangwei on 14-10-16. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import "Nure.h" #import "Children.h" @implementation Nure - (id) init{ self = [super init]; if(self != nil){ //監聽一個通知,當收到通知時,調用notificationAction方法 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationAction) name:@"happyValueNotification" object:nil]; } return self; } - (void) notificationAction:(NSNotification *)notification{ //這裏咱們拿到Children對象進行操做 Children *children = notification.object; NSLog(@"觸發通知"); } - (void)dealloc{ //移除指定的通知,否則會形成內存泄露 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"happyValueNotification" object:nil]; //Children對象能夠添加多個通知 //下面的方法是能夠移除Children中全部通知 [[NSNotificationCenter defaultCenter] removeObserver:self]; } @end在Nure類中咱們開始接受通知了:
//監聽一個通知,當收到通知時,調用notificationAction方法 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationAction) name:@"happyValueNotification" object:nil];使用addObserver方法來監聽通知
第一個參數:監聽者對象ip
第二個參數:監聽處理邏輯的方法
第三個參數:通知的名稱
第四個參數:通知發送的時候傳遞過來的參數對象
一、處理通知的方法
- (void) notificationAction:(NSNotification *)notification{ //這裏咱們拿到Children對象進行操做 Children *children = notification.object; NSLog(@"觸發通知"); }這裏會傳遞一個NSNotification對象,經過object屬性能夠獲取到監聽對象了,由於咱們在發送通知的時候傳遞過來的這個對象。那麼這裏咱們就能夠獲取監聽對象的屬性值了,可是這裏咱們若是想知道屬性值變化前和變化後的值,咱們能夠在Children類中在定義一個屬性專門用來記錄舊的屬性值,這樣就能夠了。
二、銷燬方法
- (void)dealloc{ //移除指定的通知,否則會形成內存泄露 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"happyValueNotification" object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self]; }
在銷燬的方法中,咱們能夠須要移除監聽者,傳遞過去通知名
可是這裏咱們會注意到,還有一個方法:removeObserver方法,是用來移除全部監聽者的,由於可能有多個監聽者。
總結
OC中KVO操做和通知都是很重要的一個操做,他們的原理是基於觀察者模式的,可是KVO操做沒有通知靈活。可是KVO也有本身的優勢,好比能夠記錄新舊值,這個通知就比較麻煩點了,因此咱們在使用的時候視狀況而定,通常監聽屬性值變化的咱們仍是使用KVO.