ios obj-c KVO模式的介绍和使用

来源:互联网 发布:药房软件 编辑:程序博客网 时间:2024/04/30 07:00

在项目需求中,其中有一个需求是监听某个自定义View的隐藏显示来进行其他操作,比如说自定义View里面有个UITextField,当软键盘显示时,隐藏该自定义View的时候需要把软键盘也隐藏掉,这时候如果在依赖该自定义view的类当中进行判断的话,需要把每一次隐藏该自定义View的地方都进行一次隐藏软键盘的操作。

操作软键盘的人都知道软键盘都是依赖UITextField的对象的,哪个UITextField对象显示的软键盘,就用哪个UITextField的对象隐藏软键盘。可能我比较菜,不知道有更便捷的方法。

//通过UITextField对象隐藏软键盘[self.textField resignFirstResponder];

//——————–可爱的分割线———————————

以上都是废话,接下来才是kvo相关的,哈哈

KVO是键值观察者(key-value-observing)的意思,是指对一个对象当中的属性进行监听变化的操作,ios中的一种观察者模式。

具体的操作就是对某个对象中的某个属性以字符串的形式进行注册它(需要监听的属性)的观察者,指定谁来观察它,然后该属性进行变化的时候,然后该属性的观察者就能收到消息,第一时间知道它改变了,收到消息的观察者就会做出相应的操作。观察者模式有助于两个类进行解耦合。

//注册的方法- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
  • observer:观察者对象,指定谁来观察该属性
  • keyPath:需要观察的属性,以字符串形式
  • options:属性配置,四种模式
    1. NSKeyValueObservingOptionNew:属性改变后才进行通知观察者
    2. NSKeyValueObservingOptionOld:属性改变前就通知观察者
    3. NSKeyValueObservingOptionInitial:注册后就发送通知观察者
    4. NSKeyValueObservingOptionPrior:属性改变前和改变后都会通知观察者,相当于改变一次,通知两次
  • context:用来区分消息的上下文
//属性改变后回调给观察者- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;
  • keyPath:观察的属性
  • object:观察者的对象
  • change:对应注册方法的options参数,字典类型,存储配置的类型,可以进行判断改变状态
  • context:上下文,用来区分消息的来源

//——————–可爱的分割线———————————

好了,最开始讲解了需求,之后又简单的说明了KVO模式,然后接下来就是KVO的使用,也就是利用KVO模式解决以上需求,然后更好地对自定义类的封装。(作为一个稍微有点逼格的程序员,至少要能封装点东西,还要会点设计模式,哈哈哈)

上面说了,自定义View隐藏之后,如果软键盘有显示的话,要跟着隐藏,在没有使用kvo的时候,自定义View本身是不知道自己什么时候会隐藏的,所以会在依赖该自定义View的类当中,在该自定义View隐藏的时候,对软键盘进行隐藏,这时候该自定义View就得暴露个方法进行隐藏软键盘,这时候耦合性就增加了。

这时候kvo模式登场,让自定义view自己监听自己是否隐藏还是显示,如果是显示状态改变为隐藏状态,让其软键盘隐藏。

[self addObserver:self forKeyPath:@"hidden" options:NSKeyValueObservingOptionNew context:nil];

然后自己实现回调方法:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{    if (self==object&&[@"hidden" isEqualToString:keyPath]) {        if ([[change objectForKey:@"new"] intValue]==1) {            [self.textField resignFirstResponder];            NSLog(@"self的hidden属性改变了%@",[change objectForKey:@"new"]);        }else{            NSLog(@"self的hidden属性改变了%@",[change objectForKey:@"new"]);        }    }}

这时候就不需要暴露一个隐藏软键盘的方法了,在依赖该自定义View的类中,任何地方隐藏自定义View,软键盘都会跟着消失,哈哈哈哈,最后提醒下,在该自定义View中的结束方法中移除掉该kvo,不然会占用无用的资源。

- (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath- (void)removeObserver:(NSObject *)observer     forKeyPath:(NSString *)keyPath  context:(void *)context
-(void)removeFromSuperview{    [self removeObserver:self forKeyPath:@"hidden"];}

QQ:361561789
Email:voctex@163.com
Github:https://github.com/voctex

原创粉丝点击