iOS学习笔记

通知NSNotification

2019-12-11  本文已影响0人  LPL_d5fc

通知基本使用,如图

需要注意的有两点:

1.使用通知,一定要先创建监听者,再发送通知,不然是接收不到通知的。

2.使用通知之后,要在dealloc方法中释放监听。下图中如果使用第一种监听方式,就按图中的代码移除监听就可以。如果是使用第二种方式监听通知,那么我们要知道,第二种监听方法会返回一个id类型的observe(监听者),在使用的时候,我们需要创建一个属性,接收这个返回的监听者对象,移除的时候,使用_调用属性移除就好了。(替换掉self即可)

多线程使用通知

1.通知分为发送方,接收方。接收方所在线程一般由发送方所在线程决定。

举个例子:主线程建立监听,在子线程中发送通知,那么在接收到通知后,所执行的代码是在发送通知的子线程中执行的。

总结:接收到通知后,执行的代码在哪里执行,由发出通知的线程决定

2.但是在上图监听方式二中,我们可以通过传入queue参数控制代码在什么线程中执行,很方便。

说一个小问题,异步监听,主线程发通知的情况,可能会监听不到通知,因为异步执行,代码执行顺序不确定,可能是先发送了通知,后创建的监听者导致的。要注意一下。

3.异步发送通知注意点(使用通知队列(NSNotificationQueue)情况下的注意点)

如果异步使用通知中心发送通知,是没有影响的(通知中心是默认立即发送的)。但是如果异步使用NSNotificationQueue发送通知,传入参数的模式不同,可能会导致监听者无法收到通知。上代码:

如图,我们在主线程中创建观察,开启异步发送一个通知。

打印如下,可见监听方法lplReceived方法并没有执行。

原因分析:因为我们异步发送通知时,使用了通知队列(其实与队列关系不大),主要原因是我们传入的第二个参数为:NSPostWhenIdle(等待runloop空闲时发送)。因为不是立即发送,所以可能这个子线程任务执行完毕时,我们放入通知队列中的通知仍没有发送出去,然后子线程执行完任务销毁了,通知自然就发送失败了。

解决方法:

1.线程保活,开启子线程runloop,让子线程不被销毁即可。 

2.将第二个参数改为传入NSPostNow(立即发送),也是可以的。

我们这里使用的方案一,结果如图

从打印也证明出了,监听方法的执行所在线程,是与发送通知的线程一致的。(我们的监听是在主线程中的)

这里提一嘴,正常我们使用的NSNotificationCenter,默认就是立即发送的。

再记录一点,发送通知后,要同步等待监听通知方法执行完毕之后,才会继续执行发送通知后面的代码,上代码

在viewController中的touch方法中发送通知

监听通知

监听调用方法

打印情况

可以看出,发送通知后,要先执行监听方法,然后再回来继续执行发送通知后面的代码。

上一篇 下一篇

猜你喜欢

热点阅读