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看起来容易。

posted @ 2014-12-17 16:32  番茄程序员  阅读(194)  评论(0)    收藏  举报