美文网首页
NSNotification 特征探究

NSNotification 特征探究

作者: bonoCat | 来源:发表于2017-10-16 17:03 被阅读30次

NSNotification 平时用的还是比较多的。我们知道通知是同步的,并且通知的处理是与发送处于一个线程中。这就引发了一个问题,通知和线程的关系?

NSNotification 与线程之间的关系

1.开启一个线程发送一个通知

...
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNoti) name:@"customNotification" object:nil];
    
    [NSThread detachNewThreadSelector:@selector(sendNoti) toTarget:self withObject:nil];
}
...

- (void)sendNoti{
    NSLog(@"%@", [NSThread currentThread]);
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"customNotification" object:nil];
}

- (void)handleNoti
{
    NSLog(@"%@", [NSThread currentThread]);
}

通过log日志可以看出都是在同一个线程中执行的。但是并不能解决问题

NSNotificationQueue

在 NSNotificationQueue 的文档介绍中有这么一句话

Every thread has a default notification queue, which is associated with the default notification center for the task. You can create your own notification queues and have multiple queues per center and thread.
大体意思就是说每个线程有一个或多个通知队列,所以通知是依赖于线程。

NSNotificationQueue 和线程是有关系的,那么现在问题是通知队列如何加载通知,通过文档可以得到一个方法,将通知加入队列。


typedef NS_OPTIONS(NSUInteger, NSNotificationCoalescing) {
    NSNotificationNoCoalescing = 0,
    NSNotificationCoalescingOnName = 1,
    NSNotificationCoalescingOnSender = 2
};


typedef NS_ENUM(NSUInteger, NSPostingStyle) {
    NSPostWhenIdle = 1,      /// 空闲时发送
    NSPostASAP = 2,          /// 尽快发送
    NSPostNow = 3            /// 现在发送
};

/**
*  postingStyle: 发送通知的时机
*  coalesceMask: 消息合并
*  modes       : runloop 运行状态
**/
- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle coalesceMask:(NSNotificationCoalescing)coalesceMask forModes:(nullable NSArray<NSRunLoopMode> *)modes;

通过 NSNotificationQueue 来发送


- (void)sendNoti{
    
    NSNotification *noti =  [NSNotification notificationWithName:@"customNotification" object:nil];
    NSNotificationQueue *queue =    [NSNotificationQueue defaultQueue];
    
    [queue enqueueNotification:noti postingStyle:NSPostWhenIdle coalesceMask:NSNotificationNoCoalescing forModes:nil];

}

这个时候可以看下打印数据,通知的处理并未执行。由于我设置的执行时机是在当前线程空闲时机,所以,在非主线程的情况下,线程执行完毕会自动销毁,所以,也就不能执行。这个时候可以修改 postingStyle 为 NSPostNow。这就能能够正常执行。(由于runloop的关系,主线程是不会被销毁的,所以不会存在这个问题)

总结:主要还是文档中的那句话,一个线程默认会有一个通知队列。线程销毁,通知也就结束。通知为先进先出,交于 NSNotificationCenter 去执行。

NSNotification如何实现异步

虽然可以通过修改 postingStyle ,让通知在空闲的时候执行,但是由于还是处于当前线程中,只能算是“伪异步”。就通知本身而言,是不能实现同步的。有文章说可以使用 NSPort 进行端口通信,来实现通知的“异步”。虽然形式上发送和处理消息可以指定线程。但本身已不是通知功能,只能说是自定义一个通知吧~

相关文章

  • NSNotification 特征探究

    NSNotification 平时用的还是比较多的。我们知道通知是同步的,并且通知的处理是与发送处于一个线程中。这...

  • NSNotification 深入探究

    使用背景 通常情况下,我们一个对象想要调用另外一个对象的方法,便是向这个对象传递消息,那么有个前提是,我们需要能找...

  • NSNotification

    发通知 NSNotification *deleteMyCommemtN =[NSNotification not...

  • 通知使用

    创建对象 NSNotification *notification =[NSNotification notifi...

  • iOS通知中心

    有关的类 NSNotification NSNotificationCenter NSNotification N...

  • 通知中心(NSNotificationCenter)总结

    一、简介 1. NSNotification 理解 NSNotification@property (readon...

  • NSNotification观察者移除问题的探究

    前言 最近需求一直挺多的,所以日子过的也就比较“充实”,就在前天偶然看到一个“NSNotification不移除在...

  • 2021-08-30,4的倍数特征

    探究 4的倍数特征 小学数学教学中,为了追求高效率,在教学2,5,3的倍数特征时,...

  • 文本特征提取(2)

    继上期文本特征提取一文以及文本的可读性探究后,继续推出文本特征提取二,从词集型、词袋型提取文本特征。 文本特征提取...

  • 14:信息技术课程素质教学法(3)

    (六)探究法——开发学生创造力 指导式探究:主要目的在于指导学生学习,亦即协助学生“学习如何学习”。特征:教师在探...

网友评论

      本文标题:NSNotification 特征探究

      本文链接:https://www.haomeiwen.com/subject/zvqluxtx.html