一、Block
它是带有局部变量的匿名函数,它是一段代码块,与C语言中的函数指针类似,可当做参数进行传值,且可以没有名字。(在我另外一篇文章中有详细介绍)
解决的问题
1.解决两个对象之间的通信问题(传值或者事件)
它既可以正向传值也可以反向传值,传递方定义好block,调用block,在调用方创建传递方的类的实例对象,在实例对象的block中实现相关代码,如果有传值就可以获取传递值进行相关操作,如果没有参数可传,则就传递了一个事件,具体看这个事件是在何种情况下传递出去的,比如A的按钮被点击,可定义一个block放在A按钮点击方法里,B想监听A中按钮点击事件,则可在B中实例化A的对象,A.block 中就可以执行A中按钮点击后,B想做的事。
2.block回调
这类似于1的一个变种,只不过把block嵌进了方法里,在调用方法完成后就执行回调block中的代码。最直接的例子就是网络请求编写的GET和POST的回调方法了。在定义处把传递值赋给block的参数,在调用处就可以取得block参数里的变量。特点
1.一对一的消息传递
2.需先声明Block,调用block,实现block,相比于delegate简直是不要太简洁。
3.能实现方法回调缺点
使用时需要注意避免循环使用的问题(使用__weak关键字修饰词可避免)。
二、Delegate
Delegate (委托/代理)是 iOS 开发中常用的设计模式,表示将一个对象的部分功能转交给另一个对象。借助 protocol 可以很方便的实现这种设计模式。
通常,一个delegate的使用过程,需要经过五步:
创建一个 delegate;
委托者声明一个delegate;
委托者调用delegate内的方法(method);
被委托者设置delegate,以便被委托者调用;
被委托者实现Delegate 所定义的方法。
解决的问题
Delegate通过protocol 实现了不同视图之间的数据交互(事件、传值,与block的功能类似)。 Delegate 属于事件驱动的范畴。只有当某一事件触发时,delegate 才被调用。特点:
1.能够接收调用的协议方法的返回值。这意味着delegate能够提供反馈信息给controller。(这是利用代理传值的一个使用)
2.实现一对一的消息传递
3..在一个类中可以定义多个不同的协议,每个协议有不同的delegates
4.协议中的方法有必须实现的,也可以有不必须实现的,但要有@optional修饰缺点:
1.定义代码太多,步骤繁琐
2.只能实现一对一的消息传递
3.有非常严格的语法(比如定义delegate不能使用强引用,只能使用弱引用)
4.不调用就不会触发协议方法
三、Notification
允许当事件发生时通知一些对象。它允许我们在低程度耦合的情况下,满足控制器与一个任意的对象进行通信的目的。这里可能会和KVO(健值观察)混淆,Notification 和 KVO 都是观察着模式,侧重点不一样。
- 解决问题
通知,是Model与Controller通信的方式之一。一般是Model发送变化的时候,会发送通知告诉Controller,Controller再做相应的处理。需要先往通知中心里面注册观察者,然后在合适的时机,通知中心post通知,观察者做对应的处理,当观察者将要释放的时候,从通知中心移除观察者。
KVO,也是M与C通讯的方式。一般是C去观察M的某个属性,某个属性发生变化之后,C做出相应的处理,当C将要释放的时候,M移除观察者。
通知往往用于多对多的场景,多个观察者观察一个通知,一旦这个通知被通知中心post,所有观察者都可以做出响应。具体的实现流程是:(1)通知中心通过addObserver方法添加观察者,其实是把观察者和通知进行绑定,多次使用addObserver方法可以为同一个通知添加多个观察者。(2)通知中心发送通知。(3)各个观察者做各自的处理。(4)在观察者销毁之前(dealloc中),从通知中心移除观察者。
KVO多用于1对1的场景,一个对象去观察另外一个对象的属性值有没有发生变化,一旦发生变化,观察者做出响应。具体的流程是:(1)被观察者添加观察者,指定观察者观察的属性。(2)被观察者的属性在某一时间发生了变化。(3)观察者做出响应。(4)在观察者销毁之前,先移除观察者。
KVO其实也可以1对多,就是多个观察者观察同一个对象同一个属性的变化。KVO和通知给人的感觉一个主动通知(通知会由通知中心主动post),一个是被动通知(KVO,观察者一直盯着属性变没变,一旦变化,自己就做出响应。被观察的对象不是主动告知你我变了)。
特点
1.不需要编写多少代码,实现比较简单;
2.对于一个发出的通知,多个对象能够做出反应,即1对多的方式实现简单
3.controller能够传递context对象(dictionary),context对象携带了关于发送通知的自定义的信息缺点
1.在编译期不会检查通知是否能够被观察者正确的处理;
2.在释放注册的对象时,需要在通知中心取消注册;
3.controller和观察者需要提前知道通知名称、UserInfo dictionary keys。如果这些没有在工作区间定义,那么会出现不同步的情况,通知就没有了意义;
6.通知发出后,controller不能从观察者获得任何的反馈信息。是否成功接收,发送者也不会知道。
总结
Block 、Delegate、Notification共同点
1.能解决不同类之间消息传递问题区别:
1.Block和Delegate都是一对一的消息传递,Notification则是多对多的消息传递