zoukankan      html  css  js  c++  java
  • iOS-KVO详解

     

    (观察者模式:注册监听、事件回调

    Key-Value-Observing一个对象能够观察另外一个对象的属性的值当指定对象的属性被修改后,则对象就会接受到通知。(简单来说就是每次指定被观察的对象的属性被修改后,KVO就会自动通知响应的观察者了)

    在OC中要实现KVO则必须实现NSKeyValueObserving协议,不过幸运的是NSObjkect已经实现了该协议。因此几乎所有的对象都可以使用KVO。

    KVO使用:

    ①被观察者发出:-(void)addObserver:(NSObject*)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context;

    ②然后只要被观察者的keyPath值发生变化(单纯改变其值不会调用此方法,只有通过getters和setters来改变值才会触发KVO),就会在观察者里调用方法:

    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context; 来对KVO发出的通知做出响应。

    ③(这些代码都只需要在观察者里进行实现,被观察者不用添加任何代码,所以谁要监听谁注册,然后对响应进行处理即可,运用灵活简单;但是KVO只能检测类中的属性,并且属性名都是通过NSString来查找,编译器不会帮你检错和补全,纯手敲所以比较容易出错、当释放观察者时不需要移除观察者)

     

    KVO实例(使用场景)

     

    1.KVO观察属性变化

     

    //1注册创建观察者
    //2有一个回调函数,对被观察者的变化,可以进行相应的处理
    //3移除或销毁创建的观察者
    People * people = [[People alloc] init];
    [people registerObservater];
    [[NSRunLoop currentRunLoop] run];
    @implementation People
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            _bank = [[Bank alloc] init];
        }
        return self;
    }
    //创建一个标识符
    static void * bankBalance = (void *)&bankBalance;
    - (void)registerObservater{
        //创建观察者
        [_bank addObserver:self forKeyPath:@"money" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:bankBalance];
    }
    //创建一个回调函数
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
        NSLog(@"%@---%@--%@----",keyPath,object,change);
        //    if ([keyPath isEqualToString:@"money"]) {
        //
        //    }
        
        //假设有多个观察者,以此来判断,不建议用上面的那个
            if (context==bankBalance) {
               
            }
    }
    //销毁观察者
    - (void)dealloc{
        [self removeObserver:self forKeyPath:@"money"];
        [super dealloc];
    }
    @end

    2.KVO传值

    @property NSString  *sendValue;  //存放点击某一行的值
    detail=[[DetailViewController alloc] init];
    //添加观察者
    [self addObserver:detail forKeyPath:@"sendValue" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
    //Cell跳转赋值操作
    self.sendValue=[NSString stringWithFormat:@"%ld",indexPath.row+1];
    //接收并显示
    //重写通知中心函数
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
        NSString *strValue=change[@"new"];
        label.text=strValue;
    }

    3.一键换肤

     

    @implementation ChangeBGTool
    + (instancetype)changeAllBackgroungColor {
        
        static ChangeBGTool * __bgColor = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            
            __bgColor = [[self alloc] init];
        });
        return __bgColor;
    }
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            self.color = [UIColor whiteColor];
        }
        return self;
    }
    @end
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        ChangeBGTool * single = [ChangeBGTool changeAllBackgroungColor];
        [single addObserver:self forKeyPath:@"color" options:NSKeyValueObservingOptionNew context:nil];
        self.view.backgroundColor = [single valueForKeyPath:@"color"];
    }
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
        UIColor * color = (UIColor *)change[@"new"];
        self.view.backgroundColor = color;
    }

    //二级界面

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view from its nib.
        ChangeBGTool * single = [ChangeBGTool changeAllBackgroungColor];
        [single addObserver:self forKeyPath:@"color" options:NSKeyValueObservingOptionNew context:nil];
         self.view.backgroundColor = [single valueForKeyPath:@"color"];
    }
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
        UIColor * color = (UIColor *)change[@"new"];
        self.view.backgroundColor = color;
    }
    - (void)dealloc
    {
        //移除观察者
        [[ChangeBGTool changeAllBackgroungColor] removeObserver:self forKeyPath:@"color" context:nil];
    }

     

     

     

     

     

     

  • 相关阅读:
    python安装
    实现node服务器
    VSCode集成tomcat及使用方法
    CommonJS规范
    Bootstrap 笔记
    vue笔记
    jgGrid模板添加
    vue组件中的data
    解析DNS
    StaticResource
  • 原文地址:https://www.cnblogs.com/StevenHuSir/p/iOS_KVO.html
Copyright © 2011-2022 走看看