標籤:style blog http io ar color os 使用 sp
A.定義 iOS程式都有一個NSNotificationCenter的單例對象,用來負責發布不同對象之間的通知 任何對象都能夠在NSNotificationCenter發布通知,發布自己的發生的事件;監聽者(Observer)可以選擇接受某個特定通知。
B.使用
1. 屬性
- - (NSString*)name; // 通知的名稱
- - (id)object; // 通知發行者(是誰要發布通知)
- - (NSDictionary*)userInfo; // 一些額外的資訊(通知發行者傳遞給通知接收者的資訊內容)
2.初始化
- + (instancetype)notificationWithName:(NSString*)aName object:(id)anObject;
- + (instancetype)notificationWithName:(NSString*)aName object:(id)anObject userInfo:(NSDictionary*)aUserInfo;
- - (instancetype)initWithName:(NSString*)name object:(id)object userInfo:(NSDictionary *)userInfo;
3.發布通知(通過NSNotificationCenter) - (void)postNotification:(NSNotification*)notification; 發布一個notification通知,可在notification對象中設定通知的名稱、通知發行者、額外資訊等 - (void)postNotificationName:(NSString*)aName object:(id)anObject; 發布一個名稱為aName的通知,anObject為這個通知的發行者 - (void)postNotificationName:(NSString*)aName object:(id)anObject userInfo:(NSDictionary*)aUserInfo; 發布一個名稱為aName的通知,anObject為這個通知的發行者,aUserInfo為額外資訊
4.設定監聽器Observer通知中樞(NSNotificationCenter)提供了方法來註冊一個監聽通知的監聽器(Observer)(1) - (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString*)aName object:(id)anObject; observer:監聽器,即誰要接收這個通知 aSelector:收到通知後,回調監聽器的這個方法,並且把通知對象當做參數傳入 aName:通知的名稱。如果為nil,那麼無論通知的名稱是什麼,監聽器都能收到這個通知 anObject:通知發行者。如果為anObject和aName都為nil,監聽器都收到所有的通知 (2) - (id)addObserverForName:(NSString*)name object:(id)obj queue:(NSOperationQueue*)queue usingBlock:(void (^)(NSNotification*note))block; name:通知的名稱 obj:通知發行者 block:收到對應的通知時,會回調這個block queue:決定了block在哪個操作隊列中執行,如果傳nil,預設在當前操作隊列中同步執行
5.在監聽器銷毀之前,取消監聽 通知中樞不會保留(retain)監聽器對象,在通知中樞註冊過的對象,必須在該對象釋放前取消註冊。否則,當相應的通知再次出現時,通知中樞仍然會向該監聽器發送訊息。因為相應的監聽器對象已經被釋放了,所以可能會導致應用崩潰 通知中樞提供了相應的方法來取消註冊監聽器 - (void)removeObserver:(id)observer; - (void)removeObserver:(id)observer name:(NSString*)aName object:(id)anObject; 一般在監聽器銷毀之前取消註冊(如在監聽器中加入下列代碼):
- (void)dealloc {
//[super dealloc]; 非ARC中需要調用此句
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
C.iOS中內建的通知 UIDevice UIDevice類提供了一個單例對象,它代表著裝置,通過它可以獲得一些裝置相關的資訊,比如電池電量值(batteryLevel)、電池狀態(batteryState)、裝置的類型(model,比如iPod、iPhone等)、裝置的系統(systemVersion) 通過[UIDevice currentDevice]可以擷取這個單例對象 UIDevice對象會不間斷地發布一些通知,下列是UIDevice對象所發布通知的名稱常量: UIDeviceOrientationDidChangeNotification// 裝置旋轉 UIDeviceBatteryStateDidChangeNotification// 電池狀態改變 UIDeviceBatteryLevelDidChangeNotification // 電池電量改變 UIDeviceProximityStateDidChangeNotification// 近距離感應器(比如裝置貼近了使用者的臉部)
D.鍵盤通知 我們經常需要在鍵盤彈出或者隱藏的時候做一些特定的操作,因此需要監聽鍵盤的狀態 鍵盤狀態改變的時候,系統會發出一些特定的通知 UIKeyboardWillShowNotification // 鍵盤即將顯示 UIKeyboardDidShowNotification //鍵盤顯示完畢 UIKeyboardWillHideNotification // 鍵盤即將隱藏 UIKeyboardDidHideNotification // 鍵盤隱藏完畢 UIKeyboardWillChangeFrameNotification // 鍵盤的位置尺寸即將發生改變 UIKeyboardDidChangeFrameNotification //鍵盤的位置尺寸改變完畢 系統發出鍵盤通知時,會附帶一下跟鍵盤有關的額外資訊(字典),字典常見的key如下: UIKeyboardFrameBeginUserInfoKey // 鍵盤剛開始的frame UIKeyboardFrameEndUserInfoKey // 鍵盤最終的frame(動畫執行完畢後) UIKeyboardAnimationDurationUserInfoKey // 鍵盤動畫的時間 UIKeyboardAnimationCurveUserInfoKey // 鍵盤動畫的執行節奏(快慢)
E.通知和代理的異同 共同點 利用通知和代理都能完成對象之間的通訊 (比如A對象告訴D對象發生了什麼事情, A對象傳遞資料給D對象) 不同點 代理 :一對一關聯性(1個對象只能告訴另1個對象發生了什麼事情) 通知 :多對多關係(1個對象能告訴N個對象發生了什麼事情, 1個對象能得知N個對象發生了什麼事情)
F.練習 類比敵我電台向外發布訊息,我方人員接收我方電台,敵方人員接收敵方電台,內奸可以接收雙方電台
1 // 2 // Radio.h 3 // Notification 4 // 5 // Created by hellovoidworld on 14/12/7. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h>10 11 @interface Radio : NSObject12 13 // 電台名稱14 @property(nonatomic, copy) NSString *name;15 16 @end
1 // 2 // Radio.m 3 // Notification 4 // 5 // Created by hellovoidworld on 14/12/7. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "Radio.h"10 11 @implementation Radio12 13 @end
1 // 2 // main.m 3 // Notification 4 // 5 // Created by hellovoidworld on 14/12/7. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h>10 #import "Radio.h"11 #import "Person.h"12 13 int main(int argc, const char * argv[]) {14 @autoreleasepool {15 Radio *r1 = [[Radio alloc] init];16 r1.name = @"我方電台";17 18 Radio *r2 = [[Radio alloc] init];19 r2.name = @"敵方電台";20 21 // 僅能接收我方電台訊息22 Person *p1 = [[Person alloc] init];23 p1.role = @"我方忠心耿耿的戰士";24 25 // 僅能接收敵方電台訊息26 Person *p2 = [[Person alloc] init];27 p2.role = @"敵方可惡的走狗";28 29 // 技能接收我方電台訊息,也能接收敵方電台訊息30 Person *p3 = [[Person alloc] init];31 p3.role = @"潛伏在我方狡猾的內奸";32 33 // 嗯,我是傳播電台電波的媒介34 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];35 36 // 1.添加監聽器37 [center addObserver:p1 selector:@selector(receiveInfoFromRadio:) name:@"attack" object:r1];38 [center addObserver:p2 selector:@selector(receiveInfoFromRadio:) name:@"defend" object:r2];39 [center addObserver:p3 selector:@selector(receiveInfoFromRadio:) name:@"attack" object:r1];40 [center addObserver:p3 selector:@selector(receiveInfoFromRadio:) name:@"defend" object:r2];41 42 // 2.我方電台r1發布攻擊資訊43 [center postNotificationName:@"attack" object:r1 userInfo:@{@"title":@"attack!, all the money belong to us!", @"title2":@"And the girls!!!"}];44 45 // 3.敵方電台r2發布回防資訊46 [center postNotificationName:@"defend" object:r2 userInfo:@{@"title":@"TP back quickly!"}];47 48 }49 return 0;50 } out:
2014-12-07 21:18:03.142 Notification[7923:714964]
我是我方忠心耿耿的戰士
,
正在接受我方電台的訊息
,
內容是
{
title = "attack!, all the money belong to us!";
title2 = "And the girls!!!";
}
2014-12-07 21:18:03.143 Notification[7923:714964]
我是潛伏在我方狡猾的內奸
,
正在接受我方電台的訊息
,
內容是
{
title = "attack!, all the money belong to us!";
title2 = "And the girls!!!";
}
2014-12-07 21:18:03.143 Notification[7923:714964]
我是敵方可惡的走狗
,
正在接受敵方電台的訊息
,
內容是
{
title = "TP back quickly!";
}
2014-12-07 21:18:03.143 Notification[7923:714964]
我是潛伏在我方狡猾的內奸
,
正在接受敵方電台的訊息
,
內容是
{
title = "TP back quickly!";
}Program ended with exit code: 0
[iOS基礎控制項 - 6.10] Notification 通知機制