zoukankan      html  css  js  c++  java
  • ios观察者模式和通知中心

    前言:IOS的观察者模式在IOS的使用频率并没有代理方法那么高,从tableView到textField,在大多数情况下,都采用的是定义代理和实现代理的方式来进行函数的回调。

    而观察者模式也只是在使用通知中心的时刻才能用到,难道是观察者模式比不上代理模式?虽然说,观察者模式在效率上不如代理模式,但是使用观察者模式可以实现程序的解耦,并且在层次结构比较深的地方,使用观察者也比层层代理更加方便。

    ----------------------------

    接下来,我们就对观察者模式进行介绍:

    观察者模式:

    观察者模式,定义了在一对多的情况下的方法回调方式,一般来说,观察者模式用于解除一个对象和多个对象间的耦合,分别是观察者和被观察者。被观察者与观察者间耦合程度降低,不管是有多少个监听者,都不需要改变被监听者的代码。

    基本过程是:

    观察者注册成为被观察者的监听者,当被观察者发生某些变化的时刻,就会触发这个监听,调用观察者中的监听方法。被观察者通常通过一个容器来存储监听者,当自身发生某些变化的时刻,就会通知这个容器中的所有监听者。

    ---------------------------

    IOS中观察者模式的实现:

    观察者模式的的思想非常简单,Subject(主题)允许别的对象——观察者(这些对象实现了观察者接口)对这个Subject的改变进行订阅和取 消订阅。当Subject发生了变化——那么Subject会将这个变化发送给所有的观察者,观察者就能对Subject的变化做出更新。在这 里,Subject是报纸的出版社,而观察者则是订阅报纸的我和你,当Subject发生变化——有新的报纸,会做出通知——将报纸发送给所有的订阅者。

    什么时刻使用观察者模式:

    当你需要将改变通知所有的对象时,而你又不知道这些对象的具体类型,此时就可以使用观察者模式。 改变发生在同一个对象中,并在别的地方需要将相关的状态进行更新

    IOS中观察者模式的实现方式:

    在iOS中观察者模式的实现有三种方法:Notification、KVO以及标准方法。

    1.Notification(使用系统提供的通知中心)

    NotificationCenter机制使用了操作系统的功能。通过NSNotificationCenter可以让对象之间进行进行通讯,这些对象相互间可以不认识。当你用一个并行的流来推送通知,或者刷新数据库,并希望在界面中能够看到时,这非常有用。(我们对系统某些事件的监听的时刻就可以使用这个方法,例如键盘抬起落下操作,某个textfield失去第一响应者的时刻,都会发送一个通知给通知中心,通过监听这些通知,我们就可以与系统交互)

    1.NSNotification * broadcastMessage = [ NSNotification notificationWithName: AnyNotification object: Self ];
    2.NSNotificationCenter * notificationCenter = [ NSNotificationCenter defaultCenter];
    3.[NotificationCenter postNotification: broadCastMessage];

    上面的代码中,创建了一个NSNotification类型的对象,并指定名称为”broadcastMessage”,然后通过notificationCenter来发布这个消息。


    要订阅感兴趣的对象中的相关事件,可以按照如下方法进行:

    1.NSNotificationCenter * notificationCenter = [ NSNotificationCenter defaultCenter];
    2.[NotificationCenter addObserver: Self selector: @ selector (update:) name: AnyNotification object: nil ];

    2.KVO

    键值观察者:通过这种方式,某个对象的某个属性发生变化的时刻,那些注册的监听者就会收到一个通知。

    例如:我们要对某一个UIlabel的text进行监听。当text变化的时刻就触发某个方法。UIlabel* label;

    KVO使用的NSObject自带的

    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

    方法,这个方法会在这个对象监听到通知的时刻调用。

    --------

    也就是说,我们可以通过覆写继承自NSObject的任何子类实现对通知的监听。注意,是任何通知,在这个方法中需要通过判断来区分不同的通知。

    从这里我们知道:其实任何继承自Object的类都是能够监听通知的,所以,任何对象都可以被addObsever到某个被监听的对象中去,然后在这个对象的observeValueForKeyPath中进行后续操作。

    3:手动通知:

    在上面的方法中,依赖的是系统给我们定义的自动通知,当某个属性发生变化的时刻,系统就会自动发送通知给监听者,而如果我们需要进一步定义通知发送时间的时刻,就应该使用手动发送通知的方式。

    willChangeValueForKey:
    didChangeValueForKey:

    这两个方法就会发送指定key的通知。

    4:自动通知:

    [self setValue:[NSNumber numberWithBool:YES]forKey:@"isFinished"]; 
    将观察者与被观察者注册好之后,就可以对观察者对象的属性进行操作,这些变更操作就会被通知给观察者对象。注意,只有遵循 KVO 方式来设置属性,观察者对象才会获取通知,也就是说遵循使用属性的 setter 方法,或通过 key-path 来设置:

    自动通知是可以关闭的,automaticallyNotifiesObserversForKey方法就是用来设定某些key值自动通知,默认是所有的属性都自动通知,通过设置某个key返回no关闭它的自动通知。在使用手动通知的时刻,一般就会关闭自动通知。
  • 相关阅读:
    平衡——职场小说《监控》推荐
    《java程序员全攻略:从小工到专家》连载一:外行人眼中的IT人
    《java程序员全攻略:从小工到专家》连载二:IT行情分布
    各路技术牛人都推荐的书
    程序员2009精华本 有哪些值得期待
    揭秘孙小小《PPT演示之道》
    In the beginning, the world was void and without form…
    大学计算机课程复习操作系统
    大学计算机课程复习汇编语言
    (转)Winform 创建桌面快捷方式并开机启动
  • 原文地址:https://www.cnblogs.com/zhonghuaxiaodangjia/p/3965881.html
Copyright © 2011-2022 走看看