iOS-9 观察者模式

有人问iOS观察者模式是什么,并介绍一下,然后回答的人张嘴就来NSNotificationCenter怎么使用,然后就GG了,看到这,也没固定思路的我立即去整理了一下。

三问三答。

观察者模式是为了解决什么问题的呢?

观察者模式的定义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。  简而言之,就是A和B,A对B的变化感兴趣,就注册为B的观察者,当B发生变化时通知A,告知B发生了变化。这个也叫做经典观察者模式。

在iOS中通过什么方案来解决的呢?

在iOS中观察者模式的实现有两种方法:Notification、KVO。

当前体系下的具体实现方案呢?

1.Notification

对于感兴趣的A来说,在这里定义通知,也就是注册观察者(A就是观察者,怎么观察的以及观察到了会做些什么)

[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(notice:) name:@"tongzhi"object:nil];-(void)notice:(id)sender{NSLog(@"%@",sender);}

对于变化源B来说,在B这里发出通知

//创建通知对象NSNotification*notification = [NSNotificationnotificationWithName:@"tongzhi"object:nil];//Name是通知的名称 object是通知的发布者(是谁要发布通知,也就是对象) userInfo是一些额外的信息(通知发布者传递给通知接收者的信息内容,字典格式)//    [NSNotification notificationWithName:@"tongzhi" object:nil userInfo:nil];//发送通知[[NSNotificationCenterdefaultCenter] postNotification:notification];

当然了,还要移除观察者,在dealloc里面

- (void)dealloc {//删除根据name和对象,如果object对象设置为nil,则删除所有叫name的,否则便删除对应的[[NSNotificationCenterdefaultCenter] removeObserver:selfname:@"tongzhi"object:nil];}

KVO全称叫Key Value Observing,顾名思义就是一种观察者模式用于监听属性的变化,KVO和NSNotification有很多相似的地方,用addObserver:forKeyPath:options:context方法 去观察,用removeObserver:forKeyPath:context去移除观察者,用observeValueForKeyPath:ofObject:change:context:去响应观察者

KVO监听属性的变化非常方便,下面举个例子

//自定义MyTimer类,在.h文件中定义一个属性name@property(nonatomic,strong)NSString*name;

//自定义ViewController,在controller的.h文件中也定义一个属性myView@property(nonatomic,strong)UIView*myView;

//在Viewcontroller的.m文件中定义一个button,设置点击事件,在该事件中分别调用上面定义的两个属性

inti =5;intsum =15;- (void)viewDidLoad {    [superviewDidLoad];self.view.backgroundColor = [UIColorwhiteColor];UIButton*btn = [UIButtonbuttonWithType:UIButtonTypeSystem];        btn.frame =CGRectMake(100,100,100,30);        [btn setTitle:@"点击"forState:UIControlStateNormal];        [btn addTarget:selfaction:@selector(handleTimer:) forControlEvents:UIControlEventTouchUpInside];        [self.view addSubview:btn];            _label = [[UILabelalloc ] initWithFrame:CGRectMake(100,200,180,30)];    _label.text =@"当前年龄15岁";    [self.view addSubview:_label];//创建Mytimer对象_ourTimer = [[MyTimer alloc ] init];//观察属性name[_ourTimer addObserver:selfforKeyPath:@"name"options:NSKeyValueObservingOptionNew||NSKeyValueChangeOldKeycontext:nil];//观察属性myView[selfaddObserver:selfforKeyPath:@"myView"options:NSKeyValueObservingOptionNew||NSKeyValueChangeOldKeycontext:nil];    }

//点击事件,分别调用属性- (void)handleTimer:(UIButton*)btn {    _ourTimer.name =@"小明";self.myView =nil;NSLog(@"第一次设置名字");}

//一旦属性被操作了,这里会自动响应(上面设置观察的属性才会在这响应)- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context {if([keyPath isEqualToString:@"name"]) {NSLog(@"名字发生了改变");        _label.text = [NSStringstringWithFormat:@"当前年龄%d岁", i + sum];        sum = i + sum;    }elseif([keyPath isEqualToString:@"myView"]) {NSLog(@"我的视图");    }}

//移除- (void)dealloc {    [_ourTimer removeObserver:selfforKeyPath:@"name"];    [selfremoveObserver:selfforKeyPath:@"myView"];    }

如果你喜欢的话,就点个赞吧。


KVO是监控自身属性的变化,如uilabel对象的,他监控自身的属性,比如可以有text等


链接:https://www.jianshu.com/p/712efd0b4457

来源:

著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

你可能感兴趣的:(iOS-9 观察者模式)