IOS观察者模式与通知中心

来源:互联网 发布:translator翻译软件 编辑:程序博客网 时间:2024/05/22 17:00

前言: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关闭它的自动通知。在使用手动通知的时刻,一般就会关闭自动通知。

5:被观察者post通知给观察者接收:

首先在你需要监听的类中加入观察者:
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;
这个观察者在监听到anObject发送名字为aName的notification时,调用selector的方法,在aSelector方法中得到userInfo。
anObject表示从谁那儿发送出来的消息。
一般的selector中的方法可以这么写:
- (void)method: (NSNotification:)sender
{
    NSDictionary *dict = [sender userInfo];
}
也就是说监听到了anObject发出消息,消息的名字是aName,此时observer就调用aSelector方法,把notification的userInfo拷贝到本地。

然后在被监听的类中发送通知:
可以使用一下三个方法:
- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSString *)aName object:(id)anObject;
- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;


1 0
原创粉丝点击