实现原理
结构设计
通知如何存储的
name&observer&SEL之间的关系
发送通知是同步还是异步
同步的,所谓的异步操作,也就是延迟发送,在合适的时机发送。通知的接受和发送在同一个线程里。
Person.m
+ (void)post {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"before %@", NSThread.currentThread);
[[NSNotificationCenter defaultCenter] postNotificationName:@"name" object:nil];
NSLog(@"after %@", NSThread.currentThread);
});
}
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test) name:@"name" object:nil];
[Person post];
}
- (void)test {
sleep(1);
NSLog(@"test %@", NSThread.currentThread);
}
---------------执行结果---------------
2020-04-15 19:41:48.735183+0800 runtime[98110:3272720] before <NSThread: 0x600002340b00>{number = 5, name = (null)}
2020-04-15 19:41:49.736964+0800 runtime[98110:3272720] test <NSThread: 0x600002340b00>{number = 5, name = (null)}
2020-04-15 19:41:49.737266+0800 runtime[98110:3272720] after <NSThread: 0x600002340b00>{number = 5, name = (null)}
如何不阻塞当前线程?
- 让通知事件处理方法在子线程中执行
- 您可以通过NSNotificationQueue的enqueueNotification:postingStyle:和enqueueNotification:postingStyle:coalesceMask:forModes:方法将通告放入队列,实现异步发送,在把通告放入队列之后,这些方法会立即将控制权返回给调用对象。
NSNotification *notification = [NSNotification notificationWithName:@"name"
object:nil];
[[NSNotificationQueue defaultQueue] enqueueNotification:notification
postingStyle:NSPostASAP];
NSNotificationQueue 是异步还是同步发送的?
NSPostingStyle的值为:
- NSPostWhenIdle和NSPostASAP:异步发送
- NSPostNow:同步发送
NSNotificationQueue和runloop的关系
NSNotificationQueue将通知添加到队列中时,其中postringStyle参数就是定义通知调用和runloop状态之间关系。
- NSPostWhenIdle:runloop空闲的时候回调通知方法
- NSPostASAP:runloop在执行timer事件或sources事件完成的时候回调通知方法
- NSPostNow:runloop立即回调通知方法
如何保证通知接受的线程在主线程
页面销毁时不移除通知会崩溃吗
- iOS9.0之前,会crash,原因:通知中心对观察者的引用是unsafe_unretained,导致当观察者释放的时候,观察者的指针值并不为nil,出现野指针。
- iOS9.0之后,不会crash,原因:通知中心对观察者的引用是weak。