观察者模式在IOS中也是总要的一种模式,被观察的对象会告诉观察它的对象发生的一些变化,这里会分为两个实现类和两个接口
下面的一个Subject类,包含两个委托ObjectDelagate和SubjectDelegate
//Subject.h #import <Foundation/Foundation.h> //观察者委托 @protocol ObserverDelegate @required -(void)update; @end //被观察者委托 @protocol SubjectDelegate @required -(void)addObserver:(id<ObserverDelegate>)observer; -(void)removeObservers:(id<ObserverDelegate>)observer; @end @interface Subject : NSObject<SubjectDelegate> +(Subject *)shareManager; @end //Subject.m #import "Subject.h" @interface Subject() @property(weak,nonatomic)NSMutableArray *observers; @end @implementation Subject static Subject *subject = nil; +(Subject *)shareManager { static dispatch_once_t one; dispatch_once(&one,^{ subject = [[Subject alloc]init]; }); return subject; } -(void)addObserver:(id<ObserverDelegate>)observer { [self.observers addObject:observer]; } -(void)removeObservers:(id<ObserverDelegate>)observer { [self.observers removeObject:observer]; } @end
下面的是Observer类
//Observer.h #import <Foundation/Foundation.h> #import "Subject.h" @interface Oberver : NSObject<ObserverDelegate> @end //Observer.m #import "Oberver.h" @implementation Oberver -(id)init { self = [super init]; if(self) { //获取到Subject的单例,然后进行观察(加入到被观察者中,如果有变化,会调用观察者的update方法) [[Subject shareManager]addObserver:self]; } return self; } -(void)update { } @end
在IOS中,有两个这样的机制是实现了观察者模式,通知(notification)机制和KVO(Key-Value Observing) 机制,下面简要介绍这两种机制。
通知机制
通知机制最主要的类是NSNotificationCenter,是单列模式。获取它的单列是[NSNotificationCenter defaultCenter],addObserver是添加观察者对象,selector是接收到通知时处理的方法,name是等待何种命令,object是接收到的数据。在下面的例子中的意思是,把自己当前的类(self)作为观察者,当某地发出"AppWillTerminateNotification"的通知的时候由观察者(self)中的handleTerminate的方法去处理接收到的通知。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTerminate:) name:@"AppWillTerminateNotification" object:nil];
下面这个是发出通知的方法,postNotificationName是发出通知的名字,object是发出通知的对象,userInfo是发出通知附带的字典,通常用于传递参数
//传参的字典 NSMutableDictionary *dict = [[NSMutableDictionary alloc]init]; [dict setValue:@"Hello" forKey:@"TalkToYou"]; //发出的通知,发出名字为AppNotification的通知 [[NSNotificationCenter defaultCenter]postNotificationName:@"AppNotification" object:self userInfo:dict];
//下面这种是可以不带userInfo的 [[NSNotificationCenter defaultCenter]postNotificationName:@"AppNotification" object:self];
在通知到的对象里面,需要实现通知到的时候实现的方法(这个方法名字是在添加观察者的时候定义的)可以从里面获取到传递的参数
-(void)action:(NSNotification *)note { NSDictionary *dict = [note userInfo]; if (dict != nil) { [dict objectForKey:@"Hello"]; } }
KVO机制
KVO机制跟通知机制有点不一样,KVO机制是当对象的某个属性更改时,直接通知观察者成员
先来看看被观察者需要写的代码部分,addObserver这里先要获取到一个观察者的对象,forKeyPath就是被观察对象的一个key,options属性变化的选项,context就是上下文,以下这句代码的意思是,被观察者通知Observer对象类,我的其中一个属性,key为"appStatus"被更改了
Observer *observer= [Observer new]; [self addObserver:subject forKeyPath:@"appStatus" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"Pass Context"];
当发出了通知之后,观察者类会收到通知,执行一下的方法,这个方法不需要继承任何的委托,继承至NSObject的所有类都会自动继承了一下的这个方法,这个方法中,keyPath就是属性的Key,ofObject就是被观察者对象,change就是一个传递的值的数据字典,context就是传递的上下文
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context { NSLog(@"Property ‘%@‘ of object ‘%@‘ changed: %@context: %@",keyPath,object,change,context); }