NSNotification相关

·  阅读 912

实现原理

结构设计

通知如何存储的

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)}
复制代码

如何不阻塞当前线程?

  1. 让通知事件处理方法在子线程中执行
  2. 您可以通过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。

如何在主线程中响应通知

分类:
阅读
标签:
分类:
阅读
标签: