通知的使用ios
[[NSNotificationCenter defaultCenter]addObserver:selfselector:@selector (noticeAction:) name:@"name" object:nil];
註冊觀察者objective-c
NSNotification* notice = [NSNotification notificationWithName:@"name" object:nil userInfo:params]; [[NSNotificationCenter defaultCenter]postNotification:notice];
建立一個通知併發送網絡
觀察者對象的註冊必定要比通知的發送提早,不然的話會接收不到通知併發
通知和delegate的基本區別異步
通知是同步仍是異步的?async
通知的移除oop
異步通知post
[[NSNotificationQueue defaultQueue]enqueueNotification:notice postingStyle:NSPostASAP]; ----------------------------------------------------------------------------------typedef NS_ENUM(NSUInteger, NSPostingStyle) { //空閒發送通知 當運行循環處於等待或空閒狀態時,發送通知,對於不重要的通知可使用。 NSPostWhenIdle = 1, //儘快發送通知 當前運行循環迭代完成時,通知將會被髮送,有點相似沒有延遲的定時器。 NSPostASAP = 2, //和postNotification同樣是同步通知 NSPostNow = 3 };
三種枚舉類型表明三種發送方式(異步/同步均可)學習
一樣的,異步發送通知的話還可使用開啓一個新的線程的方式ui
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [[NSNotificationCenter defaultCenter]postNotification:notice]; });
通知的合併(待完善)
[[NSNotificationQueue defaultQueue] enqueueNotification:notice postingStyle:NSPostASAP coalesceMask:NSNotificationNoCoalescing forModes:nil]; ----------------------------------------------------------------------------------- typedef NS_OPTIONS(NSUInteger, NSNotificationCoalescing) { // 不合成 NSNotificationNoCoalescing = 0, // 根據NSNotification的name字段進行合成 NSNotificationCoalescingOnName = 1, // 根據NSNotification的object字段進行合成 NSNotificationCoalescingOnSender = 2 };
NSNotificationQueue除了有異步通知的能力以外,也能對當前隊列的通知根據NSNotificationCoalescing類型進行合併,須要配合不一樣的NSRunLoopMode來進行
經過合併通知咱們能夠用來保證相同的通知只被發送一次
NSNotificationCenter實現原理
NSNotificationCenter使用block方式添加的觀察者
- (id<NSObject>)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block
addObserver使用一個現存的對象做爲觀察者(通常爲self),而使用block方法會建立一個匿名的(id
若是queue
爲nil,則消息是默認在post
線程中同步處理,即通知的post
與轉發是在同一線程中,不爲nil的話就會在咱們指定的隊列中執行
若是一個給定的通知觸發了多個觀察者的block
操做,則這些操做會在各自的Operation Queue
中被併發執行。因此咱們不能去假設操做的執行會按照添加觀察者的順序來執行
這個方法會返回一個匿名的觀察者對象,咱們須要手動釋放這個對象。
屬性傳值
代理傳值
在委託方定義協議,協議中聲明@required/@optional方法,聲明一個代理屬性,使用weak修飾符
在代理方遵照協議,實現協議中的方法
初始化委託對象,將委託對象的代理設置爲self(代理對象自身)
查看代理方是否實現了須要執行的選擇子(SEL),若是實現了便開始執行
if ([self.delegate respondsToSelector:@selector(codeIOS)]) { // 讓代理方執行協議中的方法 [self.delegate SEL]; }
代理傳值通常用於逆向傳值,如:A控制器跳轉到B控制器,B控制器爲委託對象,A控制器爲代理對象,B對象的代理爲A對象,那麼在B對象中能夠傳值給A對象,並在A對象中執行相應的方法
單例模式傳值
使用block代碼塊進行傳值
能夠用於數據在多個對象間傳遞,網絡請求的回調等
//在對象B中block做爲方法參數 - (void)getNextPage:(void (^)(BOOL))completeBlock{ //block能夠嵌套,第一層block能夠在最後的block體中進行回調 [self getPage:self.page complete:^(NSMutableArray *result) { if ([result count]) { self.page++; [self.musicList addObjectsFromArray:result]; if (completeBlock) { //須要回調時,執行block completeBlock(true); } }else{ if (completeBlock) { completeBlock(false); } } }]; } ------------------------------------------------------------------------------ //在對象A中isSucceed爲回調回來的值 [strongSelf.musicModel getNextPage:^(BOOL isSucceed) { if (isSucceed) { [strongSelf.waterFallCollectionView reloadData]; } }];
通知傳值