有人问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
来源:
著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。