NSNotification、delegate、kvo、block的对比

1、NSNotification(通知)

描述
有一个NSNotification Center的单例对象,允许事件发生时通知其它对象。通知中心完成观察者注册、发送通知、移除观察者操作。

使用
NSNotification的使用包括注册通知、观察者注册、发送通知、移除观察者操作。

注意
1、同一个通知注册同一个观察者多次,而且调用的方法一样。那么这个方法会调用多次。
这里写图片描述
2、移除不存在观察者的通知,不会造成奔溃。

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"Notificationame"object:nil];
//Notificationame不存在,但没问题

3、在dealloc方法里面,或者viewController的viewdidDisappear方法里面移除观察者通知。

4、可以实现单播、组波、广播、即一对一、一对多、多对一、多对多。

优点
1、代码少、实现简单。
2、传值方便、Context自身携带相应内容。

缺点
1、编译时不知道通知能否被正确处理。
2、需要注意释放注册的通知,移除观察者,否则会crash。
3、向通知中心发送通知并不能获得任何反馈信息。
4、调试的时候,程序的工作以及控制流程难跟踪。


2、delegate(委托)

描述
delegate和protocol配套使用,定义一些protocol去委托其他对象做一些事,被委托的对象处理完事件后可以反馈信息给委托方。

使用
这里写图片描述

作用
1、传值:例如tableview的datasource,通过delegate把cell返回给tableview。
2、传事件:A类发生的事件通过delegate告诉被委托方,让其考虑发生该事件后要怎么处理。 比如mvc里面的view和controller可以通过delegate传递事件,view的点击事件通过delegate传给controller让其去处理。

注意
1、delegate因为要作为属性,所以需要用weak修饰,防止循环引用。
2、在被委托方的dealloc里面把delegate置为nil。即xxxx.delegate = nil
3、委托者调用协议时候应该判断被委托者是否已经实现该协议,否则可能会crash。利用来检测respondsToSelector:@selector()。
4、在代理中调用方法的时候使用的是系统的子线程,因此当使用Delegate进行UI操作时候,必须调用GCD的主线程方法:
dispatch_async(dispatch_get_main_queue(), <^(void)block>)在block中写进行的UI操作代码。同时要防止强循环引用。

优点
1、必须实现的协议,如果没有实现会有警告。
2、使用delegate的时候,逻辑很清楚,控制流程可跟踪和识别
3、没有第三方要求保持/监视通信过程。
4、能够接受调用的协议方法的返回值,意味着delegate能够提供反馈信息给controller

缺点
1、需要定义很多代码,如protocol、controller的delegate属性、delegate本身中实现delegate方法定义。
2、.在释放delegate时,需要小心的将delegate改为nil。一旦设定失败,那么调用释放对象的方法将会出现内存crash
3、调用未实现的方法会crash。
4、一个controller中有多个delegate对象,并且delegate是遵守同一个协议时,很难告诉多个对象同一个事件,即只能一对一。
5、当实现跨层传值监听的时候将加大代码的耦合性,并且程序的层次结构将变的混乱。


3、kvo

描述
kvo全称为key value obeserver,用来监听属性的变化。KVO更加适合任何类型的对象侦听另外一个任意对象属性的改变(这里任意类型的对象也可以是controller,但一般不是controller)

注意
1、可以一对多
2、潜在的问题有可能出现在dealloc中对KVO的注销上。KVO的一种缺陷(其实不能称为缺陷,应该称为特性)是,当对同一个keypath进行两次removeObserver时会导致程序crash,这种情况常常出现在父类有一个kvo,父类在dealloc中remove了一次,子类又remove了一次的情况下。不要以为这种情况很少出现!当你封装framework开源给别人用或者多人协作开发时是有可能出现的,而且这种crash很难发现。不知道你发现没,目前的代码中context字段都是nil,那能否利用该字段来标识出到底kvo是superClass注册的,还是self注册的? 回答是可以的。我们可以分别在父类以及本类中定义各自的context字符串,比如在本类中定义context为@”ThisIsMyKVOContextNotSuper”;然后在dealloc中remove observer时指定移除的自身添加的observer。这样iOS就能知道移除的是自己的kvo,而不是父类中的kvo,避免二次remove造成crash。

优点
1、能够提供一种简单的方法实现两个对象间的同步。例如:model和view之间同步;
2、能够对非我们创建的对象,即内部对象的状态改变作出响应,而且不需要改变内部对象(SDK对象)的实现;
3、能够提供观察的属性的最新值以及先前值;

缺点
1、我们观察的属性必须使用NSStrings来定义。因此在编译器不会出现警告以及检查;
2、当释放观察者时需要移除观察者。
3、要通过遵循 KVO 的属性设置方式来变更属性值,如果仅是直接修改属性对应的成员变量,是无法实现KVO 的。

总结:KVO有显著的使用场景,当你希望监视一个属性的时候,我们选用KVO,而notification和delegate有比较相似的用处,当处理属性层的消息的事件时候,使用KVO,其他的尽量使用delegate,除非代码需要处理的东西确实很简单,那么用通知很方便


4、block

描述
Block是对象,它封装了一段代码,这段代码可以在任何时候执行。block
可以作为函数参数或函数的返回值,其本身又可以带输入参数或返回值。

注意
可参考自己写的block系列内容。

优点
1、block即代码块,在很多调用中使用block都会使得代码的逻辑更加清晰。
2、.block可以不进行命名,或者存储在临时变量之中;所以在只需要调用一次,或者在同一函数内多次调用的地方,使用block会比较方便。
3、block也可以存储在属性之中,进行多次调用;这么使用的时候,一定要注意判断block不为nil。
4、配合GCD优秀的解决多线程问题。

缺点
1、block中容易造成循环引用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值