zoukankan      html  css  js  c++  java
  • NSNotificationCenter KVO KVC Delegate Block

    面试会经常问到上述几个模式的区别,今天进行汇总:

    一:他们之间的区别

    KVO 和 KVC 的区别:
    1.KVC只针对类属性,设置键值对;
    2.设置setValue:forKey:,即forKey只能为类属性
    3.取值 valueForKey
    4.KVO 被观察者的属性发生变化时,通知观察者
    5.KVO利用KVC对类属性进行设置
    6.注册observing对象addObser:forKeyPath:options:context:
    7.观察者类必须重写方法 observeValueForKeyPath:ofObject:change:context:
    8.MVC模型中,数据库(dataModal)发生改变时,引起view改变,就用KVO实现比较简单
     
    通知与KVO的区别:
    通知是一个中心对象为所有观察者提供变更通知,KVO是被观察对象直接向观察者发送通知.
     
    代理与通知的区别:
    首先通知是发出消息后 可以有多个消息接受者(观察者),通知使用起来非常方便,我们只需要在消息需要广播的地方发出去消息,至于消息内部是怎么发的,我们不用去管,只需要在我们想要得到这个消息的地方监听即可,不用管消息是怎么到这儿的,但是如果通知过多,会造成通知的管理复杂,如果管理不好,你会接收到莫名其妙的消息,而无法追踪,它允许注册和删除观察者,代理的效率要比通知高,实现起来比较复杂,而且应用的场景没有通知多,代理发出消息后只能由某个特定的对象获取到消息。
     
    代理与block的区别:
    委托和block是IOS上实现回调的两种机制。Block基本可以代替委托的功能,而且实现起来比较简洁,比较推荐能用block的地方不要用委托,Blocks 更清晰。比如 一个 viewController 中有多个弹窗事件,Delegate 就得对每个事件进行判断识别来源。而 Blocks 就可以在创建事件的时候区分开来了。
     
    二:分别作以介绍
    通知通知中心,最典型的应用就是任何对象都可以发送通知到中心,同时任何对象可以监听中心的通知。 被观察者发布消息,观察者注册监听 ,一对多;
     
    通知的优点:
    1.不需要编写多少代码,实现比较简单

    2.对于一个发出的通知,多个对象能够做出反应,即1对多的方式实现简单

    3.controller能够传递context对象(dictionary),context对象携带了关于发送通知的自定义的信息

    4.通知的发送者和接受者都不需要知道对方。可以指定接收通知的具体方法。通知名可以是任何字符串。

    通知的缺点:

    1.不能传大量数值;

    2.在编译期不会检查通知是否能够被观察者正确的处理; 

    3.在释放注册的对象时,需要在通知中心取消注册;

    4.在调试的时候应用的工作以及控制过程难跟踪;

    5.需要第三方对喜爱那个来管理controller与观察者对象之间的联系;

    6.controller和观察者需要提前知道通知名称、UserInfo dictionary keys。如果这些没有在工作区间定义,那么会出现不同步的情况;

    7.通知发出后,controller不能从观察者获得任何的反馈信息。

    8.如果通知过多,会造成通知的管理复杂,如果管理不好,你会接收到莫名其妙的消息,而无法追踪

     通知的使用场合

    1.通知是全局的,而且是同步的,如果你要全局发送消息,并且做的事情时间不长,不会阻塞线程的话,建议使用。

    2.如果一个通知的发送者有多个接受者,而且接受的位置完全不确定,那么这种情况下用通知是比较好的方式。

    具体代码:

    //注册通知
    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(didFinish:) //didFinish:是方法名   self (谁的)和  didFinish:确定方法
    name:MPMoviePlayerPlaybackDidFinishNotification
     object:nil];
    selector是方法名  class是描述类的类  SEL method=@selector(方法名)
    通知用完要移除
    //移除通知
    [[NSNotificationCenter defaultCenter] removeObserver:self
              name:MPMoviePlayerPlaybackDidFinishNotification
                                                  object:nil];
     
    KVO 观察者模式 ,键-值-监听,监听对象的属性值的变化,观察者在键值改变时会得到通知,是基于KVC  实现的。KVO 能帮助我们让视图和模型保持同步, 相对NSNotification少了一步发送消息。
     
    KVO优点:

    1.能够提供一种简单的方法实现两个对象间的同步。例如:model和view之间同步;

    2.能够对非我们创建的对象,即内部对象的状态改变作出响应,而且不需要改变内部对象(SKD对象)的实现;

    3.能够提供观察的属性的最新值以及先前值;

    4.用key paths来观察属性,因此也可以观察嵌套对象;

    5.完成了对观察对象的抽象,因为不需要额外的代码来允许观察值能够被观察

    KVO缺点:

    1.我们观察的属性必须使用strings来定义。因此在编译器不会出现警告以及检查;

    2.对属性重构将导致我们的观察代码不再可用;

    3.复杂的“IF”语句要求对象正在观察多个值。这是因为所有的观察代码通过一个方法来指向;

    4.当释放观察者时不需要移除观察者。

    KVO使用场合你需要监听UITableview的content offset,那么当tableview滑动的时候,就会不停的收到contentoffset point值。你要监听某一对象的值的时候,建议使用。

    具体代码:
    (1)注册监听对象。anObserver指监听者,keyPath就是要监听的属性值,而context方便传输你需要的数据,它是个指针类型。
    -(void)addObserver:(NSObject *)anObserver
        forKeyPath:(NSString *)keyPath
          options:(NSKeyValueObservingOptions)options            
          context:(void *)context//(void*)是任何指针类型
    其中, options是监听的选项,也就是说明监听返回的字典包含什么值。有两个常用的选项:
    NSKeyValueObservingOptionNew 指返回的字典包含新值。
    NSKeyValueObservingOptionOld    指返回的字典包含旧值。
    (2)实现监听方法。监听方法在Value(属性的值)发生变化的时候自动调用。
    -(void) observeValueForKeyPath:(NSString *)keyPath
                          ofObject:(id)object
                            change:(NSDictionary *)change
                           context:(void *)context
    其中,object指被监听的对象。change里存储了一些变化的数据,比如变化前的数据,变化后的数据。
     
    KVC键-值-编码 ,是一种可以直接通过字符串的名字(key)来访问类实例变量的机制,通过  set get 方法访问。KVC可以用来访问和设置实例变量的值。
        key是属性名称设置方式:[self setValue:aName forKey:@"name"]
        等同于 self.name = aName;
        访问方式: aString = [self valueForKey:@"name"]
        等同于 aString = self.name;
     
    协议 : 使用了这个协议后,必须按照协议规定的内容来处理事情,协议中要求的方法必须实现(@optional的方法除外)。
    protocol是一种语法,它提供了一个很方便的、实现delegate模式的机会。
     
    代理顾名思义就是委托别人办事,当一件事情发生后,自己不处理,让别人来处理。delegate和protocol没有关系。delegate本身是一种设计模式。是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成。
     
     代理的优点:

    1.非常严格的语法。所有将听到的事件必须是在delegate协议中有清晰的定义。

    2.如果delegate中的一个方法没有实现那么就会出现编译警告/错误

    3.协议必须在controller的作用域范围内定义

    4.在一个应用中的控制流程是可跟踪的并且是可识别的;

    5.在一个控制器中可以定义定义多个不同的协议,每个协议有不同的delegates

    6.没有第三方对象要求保持/监视通信过程。

    7.能够接收调用的协议方法的返回值。这意味着delegate能够提供反馈信息给controller

    代理的缺点:

      1.需要定义很多代码:1.协议定义;2.controller的delegate属性;3.在delegate本身中实现delegate方法定义

      2.在释放代理对象时,需要小心的将delegate改为nil。一旦设定失败,那么调用释放对象的方法将会出现内存crash

      3.在一个controller中有多个delegate对象,并且delegate是遵守同一个协议,但还是很难告诉多个对象同一个事件,不过有可能。

     代理的使用场合:如果实现的接口比较多的话,建议用代理,如UITableview。

    在ClassB的头文件(ClassB.h)中定义一个代理如下:

    @interface ClassB

    @property (nonatomic, unsafe_unretained) id<ClassBDelegate> delegate;

    @end

    这样,当我们在ClassB的实现文件(ClassB.m)中遇到想让别的类(如 ClassA)处理的问题时,就可以这样

    [self.delegate methodOne];

    [self.delegate methodTwo:@"需要传递的值"];

    还有不足之处,日后总结。

  • 相关阅读:
    使用jquery的 $.grep实现es6的filter效果
    web移动前端页面,jquery判断页面滑动方向
    js for循环与for in循环的区别
    jq判断滚动条向上还是向下
    react中的hoc和修饰器@connect结合使用
    creat-react-app 如何在组件中img的src引入图片路径??
    react将字符串转义成html语句
    POJ 3905 Perfect Election (2-Sat)
    POJ 2296 Map Labeler (2-Sat)
    HDU Bomb Game 3622 (2-Sat)
  • 原文地址:https://www.cnblogs.com/zhaojian/p/5088334.html
Copyright © 2011-2022 走看看