iphone NSNotificationCenter
本文摘自:http://blog.sina.com.cn/s/blog_5df7dcaf0100c0q2.html
第十四章: 使用 Notifications
用戶可能使用RaiseMan并打開了幾個(gè)document, 然后他發(fā)現(xiàn)紫色的背景顏色實(shí)在是不利于閱讀文檔正文. 于是,他打開Preferences?panel修改背景顏色,不過令人失望的是,已經(jīng)存在的文檔的背景顏色不會(huì)跟著改變. 于是,這個(gè)用戶可能會(huì)寫信給你告訴你這些. 你也許會(huì)回復(fù):"defualts會(huì)在document創(chuàng)建的時(shí)候才讀取,保存document在打開"實(shí)際上,用戶想說明的是他希望程序能立馬刷新已經(jīng)打開的文檔. 如果這樣,那該怎么做呢?我們需要把所有打開的document用一個(gè)list記錄起來么?
--- 什么是Notification? ---
這個(gè)要求其實(shí)也很容易實(shí)現(xiàn). 每個(gè)運(yùn)行中的application都有一個(gè)NSNotificationCenter的成員變量,它的功能就類似公共欄. 對(duì)象注冊(cè)關(guān)注某個(gè)確定的notification(如果有人撿到一只小狗,就去告訴我). 我們把這些注冊(cè)對(duì)象叫做 observer. 其它的一些對(duì)象會(huì)給center發(fā)送notifications(我撿到了一只小狗). center將該notifications轉(zhuǎn)發(fā)給所有注冊(cè)對(duì)該notification感興趣的對(duì)象. 我們把這些發(fā)送notification的對(duì)象叫做 poster
很多的標(biāo)準(zhǔn)Cocoa類會(huì)發(fā)送notifications: 在改變size的時(shí)候,Window會(huì)發(fā)送notification; 選擇table view中的一行時(shí),table view會(huì)發(fā)送notification;我們可以在在線幫助文檔中查看到標(biāo)準(zhǔn)cocoa對(duì)象發(fā)送的notification
在我們的例子中,我們將MyDocumet對(duì)象注冊(cè)為observer. 而preference?controller在用戶改變color時(shí)將發(fā)送notification. MyDocument在接受到該notification后改變background?color
在MyDocument對(duì)象釋放前,我們必須從notification?center移除我們注冊(cè)的observer. 一般我們?cè)赿ealloc方法中做這件事
-- Notifications?不是什么 --
當(dāng)程序員們聽到notification?center的時(shí)候, 他們可能會(huì)聯(lián)想到IPC(進(jìn)程間通訊).他們認(rèn)為:"我在一個(gè)程序中創(chuàng)建一個(gè)observer,然后在另外一個(gè)程序中發(fā)送一個(gè)notification". 這個(gè)設(shè)計(jì)沒有辦法工作的, notification center允許同一個(gè)程序中的不同對(duì)象通許,它不能跨越不同的程序 [Notification 就是設(shè)計(jì)模式中的 觀察者模式, cocoa為我們實(shí)現(xiàn)了該模式, 就像Java也有同樣的實(shí)現(xiàn)一樣]
-- NSNotification?和 NSNotificationCenter
Notification對(duì)象非常簡(jiǎn)單. 它就是poster要提供給observer的信息包裹. notification對(duì)象有兩個(gè)重要的成員變量: name 和 object. 一般object都是指向poster(為了讓observer在接受到notification時(shí)可以回調(diào)到poster)
所以,notification有兩個(gè)方法
????- (NSString *)name
????- (id)object
NSNotificaitonCernter是架構(gòu)的大腦了.它允許我們注冊(cè)observer對(duì)象, 發(fā)送notification, 撤銷observer對(duì)象注冊(cè)
下面是它的一些常用方法
+ (NSNotificationCenter *)defaultCenter
返回notification center [類方法,返回全局對(duì)象, 單件模式.cocoa的很多的全局對(duì)象都是通過類似方法實(shí)現(xiàn)]
- (void)addObserver:(id)anObserver
???????????selector:(SEL)aSelector
???????????????name:(NSString *)notificationName
?????????????object:(id)anObject
注冊(cè)anObserver對(duì)象:接受名字為notificationName, 發(fā)送者為anObject的notification. 當(dāng)anObject發(fā)送名字為notificationName的notification時(shí), 將會(huì)調(diào)用anObserver的aSelector方法,參數(shù)為該notification 如圖14.1
. 如果notificationName為nil. 那么notification?center將anObject發(fā)送的所有notification轉(zhuǎn)發(fā)給observer
. 如果anObject為nil.那么notification center將所有名字為notificationName的notification轉(zhuǎn)發(fā)給observer
- (void)postNotification:(NSNotification *)notification
發(fā)送notification至notification?center 如圖14.2
- (void)postNotificationName:(NSString *)aName
??????????????????????object:(id)anObject
創(chuàng)建并發(fā)送一個(gè)notification
- (void)removeObserver:(id)observer
移除observer
-- 發(fā)送一個(gè)Notification?--
發(fā)送notification是其中最簡(jiǎn)單的步驟了,所以我們從它開始實(shí)現(xiàn).當(dāng)我們接收到changeBackgroundColor:消息時(shí), PreferenceController對(duì)象發(fā)送一個(gè)notification.
我們將notification命名為@"BNRColorChanged" ,我們使用一個(gè)全局常量來指定.(有經(jīng)驗(yàn)的程序員會(huì)使用一個(gè)前綴,這樣避免和其他組件定義的notification混淆)打開PreferenceController.h 添加下面的的外部申明
extern NSString * const BNRColorChangedNotification;
在PreferenceController.m中定義常量
NSString * const BNRColorChangedNotification?= @"BNRColorChanged";
在PreferenceController.m修改changeBackgroundColor:方法
- (IBAction)changeBackgroundColor:(id)sender
{
????NSColor *color = [colorWell color];
????NSData *colorAsData?=
??????????????????[NSKeyedArchiver?archivedDataWithRootObject:color];
????[[NSUserDefaults?standardUserDefaults] setObject:colorAsData
??????????????????????????????????????????forKey:BNRTableBgColorKey];
????NSNotificationCenter?*nc = [NSNotificationCenter?defaultCenter];
????NSLog(@"Sending notification");
????[nc postNotificationName:BNRColorChangedNotification?object:self];
}
-- 注冊(cè)成為Observer --
要注冊(cè)一個(gè)observer, 我們必須提供幾個(gè)要數(shù): 要成為observer的對(duì)象;所感興趣的notification的名字;當(dāng)notification發(fā)送時(shí)要調(diào)用的方法. 我們也可以指定要關(guān)注莫個(gè)對(duì)象的notification.(比如說,我們需要關(guān)注莫個(gè)特定的window的resize的notification)
編輯MyDocument類的init方法
- (id)init
{
????if (![super init])
????????return nil;
????employees = [[NSMutableArray?alloc] init];
????NSNotificationCenter?*nc = [NSNotificationCenter?defaultCenter];
????[nc addObserver:self
???????????selector:@selector(handleColorChange:)
???????????????name:BNRColorChangedNotification
?????????????object:nil];
????NSLog(@"Registered?with notification?center");
????return self;
}
同時(shí)在dealloc方法,將MyDocument從notification?center中移除
- (void)dealloc
{
????[self setEmployees:nil];
????NSNotificationCenter?*nc = [NSNotificationCenter?defaultCenter];
????[nc removeObserver:self];
????[super dealloc];
}
-- 處理Notification?--
當(dāng)一個(gè)notification發(fā)生時(shí), handleColorChange:方法將被調(diào)用. 目前我們?cè)诜椒ㄖ泻?jiǎn)單的打印一些log.
- (void)handleColorChange:(NSNotification?*)note
{
????NSLog(@"Received notification: %@", note);
}
編譯運(yùn)行程序,看到了我們想要的log了吧
-- userInfo Dictionary?--
notification對(duì)象的object變量是poster,如果我們想要notification對(duì)象傳遞更多的信息,我們可以使用user info dictionary. 每個(gè)notification對(duì)象有一個(gè)變量叫 userInfo, 它是一個(gè)NSDictionary對(duì)象,用來存放用戶希望隨著notification一起傳遞到observer的其它信息. MyDocument將使用它來得到要改變的color.在PreferenceController.m添加userInfo
- (IBAction)changeBackgroundColor:(id)sender
{
????NSColor *color = [sender color];
????NSData *colorAsData;
????colorAsData = [NSKeyedArchiver archivedDataWithRootObject:color];
????[[NSUserDefaults standardUserDefaults] setObject:colorAsData
??????????????????????????????????????????forKey:BNRTableBgColorKey];
????NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
????NSLog(@"Sending notification");
????NSDictionary *d = [NSDictionary dictionaryWithObject:color
??????????????????????????????????????????????????forKey:@"color"];
????[nc postNotificationName:BNRColorChangedNotification
??????????????????????object:self
????????????????????userInfo:d];
}
在MyDocument.m,從userInfo中讀取到color
- (void)handleColorChange:(NSNotification *)note
{
????NSLog(@"Received notification: %@", note);
????NSColor *color = [[note userInfo] objectForKey:@"color"];
????[tableView setBackgroundColor:color];
}
打開幾個(gè)窗口,并改變背景顏色,現(xiàn)在,那些打開的窗口的背景顏色立馬就變了.
-- 思考 --
通常當(dāng)你將自己的一個(gè)對(duì)象設(shè)置為cocoa某個(gè)標(biāo)準(zhǔn)對(duì)象的delegate的時(shí)候,你同時(shí)或許也對(duì)該標(biāo)準(zhǔn)對(duì)象的notification感興趣. 例如,我們實(shí)現(xiàn)一個(gè)window的delegate來處理 windowShouldClose: , 我們也許會(huì)對(duì) NSWindowDidResizeNotification這樣的notification感興趣.
如果一個(gè)cocoa標(biāo)準(zhǔn)對(duì)象有一個(gè)delegate,同時(shí)它也發(fā)送notification的話, cocoa對(duì)象會(huì)自動(dòng)將它的delegate對(duì)象注冊(cè)成為observer來接受接受自己的notification. 如果我們實(shí)現(xiàn)了一個(gè)delegate,那么delegate[也就是我們的對(duì)象]要怎樣聲明來接受notification呢?[方法的名字是什么?]
方法名字其實(shí)很簡(jiǎn)單: 以notification名字為基準(zhǔn), 先將NS前綴去掉,接著將第一個(gè)字母改為小寫. 在將后面的Notification去掉,然后加個(gè)冒號(hào):. 例如,為了能接受到window的NSWindowDidResizeNotification, delegate可以實(shí)現(xiàn)方法:
- (void)windowDidResize:(NSNotification *)aNotification
當(dāng)window改變大小時(shí),這個(gè)方法將自動(dòng)調(diào)用. 對(duì)于NSWindow,我們可以在.h或是幫助文檔中找到類似的notification 來實(shí)現(xiàn)notification方法.
?NSNotificationCenter_Demo下載?
?
轉(zhuǎn)載于:https://www.cnblogs.com/85538649/archive/2012/01/09/2316866.html
總結(jié)
以上是生活随笔為你收集整理的iphone NSNotificationCenter的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑dnf,DNF卡顿如何解决_DNF卡
- 下一篇: myeclipse 运行速度慢的解决方案