zoukankan      html  css  js  c++  java
  • QF——OC中的KVC,KVO

    KVC: (Key Value Coding) 键值编码

      所谓KVC,其实就是不通过set和get方法访问对象属性,而是通过属性名字符串动态的去读取属性。KVC其实也是OC反射机制的一种运用。

      之所以每个对象都有KVC能力,是因为NSObject类实现了NSKeyValueCoding协议。

      属性赋值: setValue:属性值 forKey:属性名

      属性读取:   valueForKey:属性名

       KVC比较常用的用处是在网络请求后要把得到NSDictionary数据要装入Model中,若要通过以往set方法赋值很麻烦,这时可以采用KVC方式,即model对象调用 setValuesForKeysWithDictionary:方法。这样简单粗暴,但是要注意参数dict中的键要和model的属性对应。一般必须要重写

    KVO:(Key Value Observer)键值监听

      KVO的实现是因为NSObject类实现了NSKeyValueObserver协议,所以每个类都有KVO能力。

      当我们对对象的某属性敏感时,可以对该属性添加观察者,当该对象的这个属性值发生改变时就会触发回调方法。

      它的本质是观察者模式。(不过添加观察者和回调方法都是自己的方式,有别于观察者模式)

             KVO一般应用在数据模型值发生改变,UI界面随即显示新值。给model某属性添加观察,当值改变时触发回调方法:改变UI的UIlabel的的内容。

      实现KVO的步骤:

        1.给对象的某属性注册观察者(监听者):

        2.重写回调方法(当属性改变时触发)

        3.重写dealloc方法,在里面销毁观察者。

    KVO和通知中心的本质都是观察模式,不过KVO是对于任何对象的属性都可以被观察;但通知中心是系统提供的,而且它是单例的。

    Person.h

    #import <Foundation/Foundation.h>
    #import "BankCard.h"
    
    @interface Person : NSObject
    
    @property(nonatomic,copy) NSString * name;
    @property(nonatomic,retain)BankCard * card;
    
    @end

    Person.m

    #import "Person.h"
    
    @implementation Person
    
    - (void)setCard:(BankCard *)card
    {
        _card = card;
        [self.card addObserver:self forKeyPath:@"money" options:NSKeyValueObservingOptionNew context:nil];  //为card属性的money项注册观察者(监听器)
    }
    
    //重写observeValueForKeyPath方法。回调方法,若money值发生改变,则触发
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        if([keyPath isEqualToString:@"money"])
        {
            NSLog(@"您账户的余额发生变动,余额为%i",self.card.money);
        }
    }
    
    
    //重写dealloc方法,移除监听。当
    - (void)dealloc
    {
        [self.card removeObserver:self forKeyPath:@"money"]; //移除监听
    }
    
    @end

    BankCard.h

    #import <Foundation/Foundation.h>
    
    @interface BankCard : NSObject
    
    @property(nonatomic,assign) long cardID;
    @property(nonatomic,assign) int money;
    
    @end

    BankCard.m

    #import "BankCard.h"
    
    @implementation BankCard
    
    
    
    @end

    main.m

    #import <Foundation/Foundation.h>
    #import "Person.h"
    #import "BankCard.h"
    
    int main(int argc, const char * argv[])
    {
    
        @autoreleasepool {
            
            Person * person = [[Person alloc]init];
            BankCard * card = [[BankCard alloc]init];
            card.money = 1000;
            person.card = card;
            
            NSLog(@"卡被盗了后...");
            card.money = 0;
            
            
        }
        return 0;
    }

    在Person类中,为card属性的money项注册了监听器,当银行卡被盗了后,人家把余额取完了。因为money的值发生了改变,所以重写的回调方法触发。

    参考:点击进入 

  • 相关阅读:
    hyper虚拟机下对centos进行动态扩容
    《C#高级编程第七版》多线程之Events
    借鉴StanZhai核心代码,写了个博客园采集器
    文档转换之PDF转换为HTML
    书香电子书下载地址分析器
    c#常用类库及资源
    iis7.5 配置伪静态
    根据枚举类型获取描述
    从客户端检测到有潜在危险的Request.Form值
    Sql行列转换
  • 原文地址:https://www.cnblogs.com/wangerxiansheng/p/4321647.html
Copyright © 2011-2022 走看看