一锁施、通知使用的回顧
-
1.1挑胸、通知使用一
-
添加通知
/** 添加通知 observer:觀察者 aSelector:只要一監(jiān)聽到通知就會調用觀察者這個方法 aName:通知名稱 anObject:誰發(fā)出的通知或者是一些參數(shù) - (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject; */ [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(reciveNote) name:@"note" object:nil];
-
發(fā)送通知
/** 發(fā)送通知 aName:通知名稱 anObject:誰發(fā)出的通知或者是一些參數(shù) - (void)postNotificationName:(NSNotificationName:)aName object:(nullable id)anObject; */ [[NSNotificationCenter defaultCenter]postNotificationName:@"note" object:nil];
-
接收通知的消息
-(void)reciveNote:(NSNotification *)notify{ NSLog(@"通知"); }
-
移除通知
-(void)dealloc{ [[NSNotificationCenter defaultCenter]removeObserver:self]; }
-
-
1.2、通知使用二(block的通知)
-
定義監(jiān)聽的返回值
@property (nonatomic, weak) id observe;
-
添加通知
/** name:通知名稱 object:誰發(fā)出的通知 queue:決定block在哪個線程執(zhí)行夷狰,nil:在發(fā)布通知的線程中執(zhí)行 usingBlock:只要監(jiān)聽到通知岭皂,就會執(zhí)行該blocl - (id <NSObject>)addObserverForName:(nullable NSNotificationName)name object:(nullable id)obj queue:(nullable NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); 注意:一定要移除通知 */ self.observe = [[NSNotificationCenter defaultCenter]addObserverForName:@"note" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { // 只要監(jiān)聽到通知就會被調用 NSLog(@"當前的線程=%@",[NSThread currentThread]); NSLog(@"%@",self); }];
-
發(fā)送通知
/** 發(fā)送通知 aName:通知名稱 anObject:誰發(fā)出的通知 - (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject; */ [[NSNotificationCenter defaultCenter]postNotificationName:@"note" object:nil];
-
移除通知
[[NSNotificationCenter defaultCenter]removeObserver:self.observe];
注意:一定要移除通知
-
二、通知多線程的使用
-
2.1沼头、利用
1.1
的通知方式-
異步 添加通知
// 監(jiān)聽通知:異步 dispatch_async(dispatch_get_global_queue(0, 0), ^{ [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(reciveNote:) name:@"note" object:nil]; });
-
異步 發(fā)送通知
dispatch_async(dispatch_get_global_queue(0, 0), ^{ [[NSNotificationCenter defaultCenter]postNotificationName:@"note" object:nil]; });
提示:接收通知的方法里面打印的是:
子線程
-
同步 發(fā)送通知
dispatch_sync(dispatch_get_global_queue(0, 0), ^{ [[NSNotificationCenter defaultCenter]postNotificationName:@"note" object:nil]; });
提示:接收通知的方法里面打印的是:
主線程
-
接收通知的消息
-(void)reciveNote:(NSNotification *)notify{ NSLog(@"當前接收通知的線程=%@",[NSThread currentThread]); }
提示:很多時候我們可能不知道發(fā)送通知的線程爷绘,我們需要在接收通知的方法里面進行更新UI,我們可以在接收方法里面使用主線程,如下
-(void)reciveNote:(NSNotification *)notify{ NSLog(@"當前接收通知的線程=%@",[NSThread currentThread]); dispatch_sync(dispatch_get_main_queue(), ^{ // 在此刷新UI }); }
-
移除通知
-(void)dealloc{ [[NSNotificationCenter defaultCenter]removeObserver:self]; }
結論:不管添加通知在主線程還是子線程进倍,接收通知的方法所在的線程是由發(fā)送通知的線程決定的土至。
-
-
2.2、利用
1.2
的通知方式:和上面的一樣猾昆,我直接說有關刷新的問題self.observe = [[NSNotificationCenter defaultCenter]addObserverForName:@"note" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { // 只要監(jiān)聽到通知就會被調用 NSLog(@"當前的線程=%@",[NSThread currentThread]); NSLog(@"%@",self); }];
-
分析:如果上面的是:
queue
為nil
,那么block里面的線程是由發(fā)送通知的線程決定陶因,那么如果block里面是子線程我們就無法刷新UI了,解決辦法是把 nil 改為[NSOperationQueue mainQueue]
,不管發(fā)送通知的線程是什么垂蜗,block里面都是主線程楷扬,如下self.observe = [[NSNotificationCenter defaultCenter]addObserverForName:@"note" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) { // 只要監(jiān)聽到通知就會被調用 NSLog(@"當前的線程=%@",[NSThread currentThread]); }];
-
最后這是調試的 demo