Delegate、Notification、KVO 、Block
1.委托delegation;
2.通知中心Notification Center;
3.键值观察key value observing,KVO
这三种模式是IOS开发中常见的三种通信方式,这里只比较下优点和缺点。通过他们之间的优缺点的比较,使得在开发过程中合理的使用他们。
delegation
优点:
1.非常严格的语法。所有将听到的事件必须是在delegate协议中有清晰的定义。
2.如果delegate中的一个方法没有实现那么就会出现编译警告/错误
3.协议必须在controller的作用域范围内定义
4.在一个应用中的控制流程是可跟踪的并且是可识别的;
5.在一个控制器中可以定义定义多个不同的协议,每个协议有不同的delegates
说不上是优点还是缺点暂且是优点吧,因为delegates过多可能会造成代码过于臃肿如果业务逻辑很复杂的controller可能会造成代码不可读从而导致心情低落或者狂暴^o^(难道是设计的耦合度太高?),我一般的做法喜欢将delegate设置成id类型然后通过调用respondsToSelector来使用。还请大牛指点下啊^^
6.没有第三方对象要求保持/监视通信过程。
这点没有发现需要再理解一下
7.能够接收调用的协议方法的返回值。这意味着delegate能够提供反馈信息给controller
缺点:
1.需要定义很多代码:1.协议定义;2.controller的delegate属性;3.在delegate本身中实现delegate方法定义
2.在释放代理对象时,需要小心的将delegate改为nil。一旦设定失败,那么调用释放对象的方法将会出现内存crash
3.在一个controller中有多个delegate对象,并且delegate是遵守同一个协议,但还是很难告诉多个对象同一个事件,不过有可能。
Notification
个人很少使用notification这种方式,先说下个人看法,notification虽然使用简单,但是使用notification时会出现大量的宏定义/字符串常量这样会导致程序不易读,并且notification是一对多的一种形式(这是一对多的解决方案),如果大量的使用不便于后期的代码维护,特别是在定义notification重名时将造成异常和潜在错误。个人是使用notification的原则是不到万不得已不使用notification.
优点:
1.不需要编写多少代码,实现比较简单;
2.对于一个发出的通知,多个对象能够做出反应,即1对多的方式实现简单
3.controller能够传递context对象(dictionary),context对象携带了关于发送通知的自定义的信息
缺点:
1.在编译期不会检查通知是否能够被观察者正确的处理;
2.在释放注册的对象时,需要在通知中心取消注册;
3.在调试的时候应用的工作以及控制过程难跟踪;
4.需要第三方对喜爱那个来管理controller与观察者对象之间的联系;
5.controller和观察者需要提前知道通知名称如果这些没有在工作区间定义,那么会出现不同步的情况;
6.通知发出后,controller不能从观察者获得任何的反馈信息。
KVO
个人在项目中很少使用。
优点:
1.能够提供一种简单的方法实现两个对象间的同步。例如:model和view之间同步;
2.能够对非我们创建的对象,即内部对象的状态改变作出响应,而且不需要改变内部对象(SKD对象)的实现;
3.能够提供观察的属性的最新值以及先前值;
4.用key paths来观察属性,因此也可以观察嵌套对象;
5.完成了对观察对象的抽象,因为不需要额外的代码来允许观察值能够被观察
缺点:
1.我们观察的属性必须使用strings来定义。因此在编译器不会出现警告以及检查;
2.对属性重构将导致我们的观察代码不再可用;
3.复杂的“IF”语句要求对象正在观察多个值。这是因为所有的观察代码通过一个方法来指向;
这个在项目中遇到过,当时使用的时监听UITextField的Text值。
4.当释放观察者时不需要移除观察者。
不移除可能会造成程序Crash等异常问题
block
还有一种方式是使用Block在controller之间进行传值。
在firstViewController中Button的点击事件
1 - (IBAction)testAction:(id)sender { 2 blockViewController *vc=[[blockViewController alloc] initWithNibName:@"blockViewController" bundle:nil]; 3 [self.navigationController pushViewController:vc animated:YES]; 4 vc.callBackBlock=^(NSString *string){ 5 NSLog(@"%@",string); 6 }; 7 }
在secondViewController中Button的点击事件和定义回传的Block
@property (strong,nonatomic) void (^callBackBlock)(NSString *string); //点击返回firstViewController - (IBAction)backAction:(id)sender { if (self.callBackBlock!=nil) { self.callBackBlock(@"callBack"); } [self.navigationController popViewControllerAnimated:YES]; }
输出结果
![]()
这种方式的传值我没有使用过,如果使用Delegate进行传值我会这么做,在firstViewController中声明一个协议xxx在定义一个方法yyy然后给firstViewController:UIViewController<xxx>,在实现yyy方法,然后在secondViewController中设定代理 id<xxx>delegate,在push secondViewController之前 vc.delegate=self; 然后再back是调用 delegate的方法或者变量。(晕了,没看懂,我要狂暴!)看了上述文字,我感受到了使用block传值的好处。 我个人认为优点是代码简单清晰命令可读性高,缺点是block不太容易理解不如delegate看起来容易。

浙公网安备 33010602011771号