说完了target-action
说完了KVO
今天说另一种消息传递的方式,这种方式和KVO很像,通常也是用于一对多的情况,这种消息传递的方式就是NotificationCenter。
NotificationCenter 翻译过来就是通知中心,他和我们生活中的广播很相似。
如何使用NotificationCenter
使用NotificationCenter和KVO非常相似,一般也是分为4个步骤:
- 1.添加观察者。
- 2.实现响应方法。
- 3.发出通知。
- 4.移除观察者。
一般在使用NotificationCenter时我们通常都是直接使用系统默认的NotificationCenter
|
|
使用类方法调用他之后,我们就可以做响应的添加、发出通知、移除等操作了。
添加观察者
添加观察者有两种方式,一个是直接调用函数添加,然后再编写实现的方法,通过selector
来响应通知。
还有一种方法是使用block
,在代码块内部实现响应通知的操作。
直接添加
直接添加观察者时可以通过函数:
|
|
传递了响应的参数之后就完成了观察者的添加,那我们来看看传递的参数都有什么作用。
observer
通知的观察者,当通知post出来之后,观察者会收到响应的通知,不可以为nil。
aSelector
收到通知之后需要做的操作,当通知post出来之后,会触发该方法,当中会传递一个NSNotification
的参数。
aName
通知名称,用来区分发送通知的对象,可以为nil,但是因为应用的执行的过程中会发出很多通知,如果为nil则代表接受所有的通知。
anObject
发送的对象,也是用来区分发送通知的对象,可以为nil,当为nil时,也会接受同一通知名称的所有的通知。
一般情况下,如果我们将通知名称和发送对象都置为nil时,我们可以监听到当前通知中心的全部通知。比如:
|
|
上边一段代码执行了之后我们会发现结果如下:
|
|
所以一般情况下,添加观察者时,我们至少都会指定好通知的名称。
|
|
输出:
|
|
另外,如果我们设置了通知名,没有设置发送对象时,所有此通知名的通知都会被接收到,如果设置了发送对象:
|
|
这时候就只有buttonAClicked
buttonA被点击时才会触发通知。
使用block
使用block添加观察者时可以调用如下函数:
|
|
相比较于上一个方法,这种方法中没有指定具体的观察者,并且用block代替了触发的方法,而且新增了一个queue
。
因为用block回调来替代了触发的方法,所以在发送通知时,也不需要去某个具体观察者的方法列表中去找对应的列表了,直接执行block中的内容就可以了。
比如上边的方法,我们就可以改成这样:
|
|
这样写,可以让代码看起来更加紧凑。
而新增的queue,在默认情况下在post的线程中处理,比如这段代码:
|
|
打印出来我们就会发现:
|
|
除了这部分的不同之外,剩下的两者应该没有什么不同的地方了,还有注意一点就是第二种方法中的循环引用问题的发生。
实现响应方法
响应方法这边就不多说了,一种是通过调用,一种是通过block,但是两种都会传递一个NSNotification对象,注意不是NSNotificationCenter
,是NSNotification
。
其中包括了
|
|
一般情况下,我们可以通过userInfo来传递一些信息。
post 通知
post通知一共有三种方法。
|
|
同理,name和object也可以为nil,只不过发出去的消息并没有理你罢了。另外userInfo用来传递一些简单的信息。
比如:
|
|
|
|
这边就会输出:
|
|
移除观察者
移除观察者一共有两种方法:
|
|
第一个方法是不针对某个特定通知,移除全部观察者,第二种是有针对性的移除某个观察者。而如果在第二种方法中name和object参数都传递nil,就和第一种方法完全一样了。
一般在dealloc
中会使用第一种方法移除全部的观察者。而在viewWillDisappear
中则使用第二种方式移除。
这里注意,如果我们不在合适的时机移除观察者,导致添加了重复的观察者的话,新注册的已有名字的观察者并不会覆盖之前的观察者,而是会添加两个观察者,这会导致post时响应两次或更多,比如:
|
|
|
|
打印的结果:
|
|
最后
NotificationCenter的简单使用就这么多,以上这些内容仅供个人学习使用,如果有什么不对的地方还请各位大佬多多指教。