zoukankan      html  css  js  c++  java
  • KVO、KVC

    Key-Value Observing (简写为KVO):当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者,相当于设计模式中的观察者模式。

    KVO的优点:
    当有属性改变,KVO会提供自动的消息通知。这样的架构有很多好处。首先,开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。这是KVO 机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可 以在工程里使用。其次,KVO的架构非常的强大,可以很容易的支持多个观察者观察同一个属性,以及相关的值。

    下面我们写个简单的demo,如何使用KVO

    首先定义一个类,声明两个属性,name跟pid;

    [objc] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. @interface DataModel : NSObject  
    2. {  
    3.   
    4.   
    5.       
    6.       
    7.     NSString *name;  
    8.     NSString *pid;  
    9.       
    10.   
    11.   
    12. }  

    在controller里

    [objc] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. - (void)viewDidLoad  
    2. {  
    3.       
    4.     [super viewDidLoad];  
    5.       
    6.   
    7.       
    8.       
    9.     dm=[[DataModel alloc] init];  
    10.       
    11.       
    12.     [dm setValue:@"daren" forKey:@"name"];  
    13.     [dm setValue:@"1" forKey:@"pid"];  
    14.       
    15.     //注册成为观察者 选项参数指定了发送变更通知时提供给观察者的信息。使用NSKeyValueObservingOptionOld选项可以将初始对象值以变更字典中的一个项的形式提供给观察者。指定NSKeyValueObservingOptionNew选项可以将新的值以一个项的形式添加至变更字典。  
    16.     [dm addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];  
    17.       
    18.     testLabel=[[UILabel alloc] init];  
    19.     [testLabel setFrame:CGRectMake(20, 20, 100, 30)];  
    20.     [testLabel setBackgroundColor:[UIColor clearColor]];  
    21.     [testLabel setTintColor:[UIColor blackColor]];  
    22.       
    23.     [testLabel setText:[dm valueForKey:@"name"]];  
    24.       
    25.     [self.view addSubview:testLabel];  
    26.       
    27.       
    28.       
    29.     UIButton *testButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];  
    30.       
    31.     [testButton setFrame:CGRectMake(20, 100, 100, 70)];  
    32.       
    33.     [testButton setTitle:@"测试" forState:UIControlStateNormal];  
    34.     [testButton addTarget:self action:@selector(testPressed:) forControlEvents:UIControlEventTouchUpInside];  
    35.     [self.view addSubview:testButton];  
    36.       
    37.       
    38.       
    39.   
    40.       
    41. }  
    42.   
    43. -(void) testPressed:(id) sender  
    44. {  
    45.   
    46.       
    47.     [dm setValue:@"wangzi" forKey:@"name"];  
    48.       
    49.       
    50.   
    51.   
    52. }  
    53.   
    54.   
    55. -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context  
    56. {  
    57.   
    58.   
    59.   
    60.     if([keyPath isEqualToString:@"name"])  
    61.     {  
    62.         testLabel.text = (NSString *)[dm valueForKey:@"name"];  
    63.     }  
    64.   
    65.   
    66.   
    67.   
    68. }  
    69.   
    70.   
    71.   
    72.   
    73. - (void)dealloc  
    74. {  
    75.       
    76.       
    77.     [testLabel release];  
    78.       
    79.     [dm removeObserver:self forKeyPath:@"name"];  
    80.       
    81.     [dm release];  
    82.   
    83.       
    84.     [super dealloc];  
    85.       
    86. }  

    上述代码中,我们设置了label的文字会随着datamodel类中的一个key的值变化而变化,这就是KVO的一个简单的运用。但KVO是基于KVC实现的,那什么又是KVC。

    KVC:Key-Value Coding,直译是:键值编码。简单来讲,就是给属性设置值的;复杂来讲,根据网上的说法,KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。isa指针,如其名称所指,(就是is a kind of的意思),指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

    比如说如下的第一行KVC的代码,其实和第二行的普通代码是等效的:

    [myClass setValue:@"daren" forKey:@"name"];

    myClass._name = @"daren";

    KVC的代码会被编译器处理成:

    SEL sel = sel_get_uid ("setValue:forKey:");
    IMP method = objc_msg_lookup (myClass->isa,sel);
    method(site, sel, @"daren", @"name");

    这下KVC内部的实现就很清楚的清楚了:一个对象在调用setValue的时候:

    a.  首先根据方法名找到运行方法的时候所需要的环境参数。

    b.  它会从自己isa指针结合环境参数,找到具体的方法实现的接口。

    c.  再直接查找得来的具体的方法实现。

    和notification的区别也是在,KVO是对象之间直接的交互,而notification需要notificationCenter来做为中间交互。

    以上都是一些比较浅的理解,更深层次的原理,还需要大家来补充~~~~

  • 相关阅读:
    结对项目——电子书的字段
    痛点分析
    文本统计——字符 单词 行数
    音乐播放器需求分析
    简单的四则运算
    高德地图——一款功能强大的APP
    记一次mysql小版本升级
    Servlet/JSP面试题目-----近期总结
    【转】各种概念POJO、JAVABEAN、DAO、DTO、PO、VO、BO、SSH、EJB
    springMVC框架(二)---springMVC框架高级开发
  • 原文地址:https://www.cnblogs.com/mingjieLove00/p/5487810.html
Copyright © 2011-2022 走看看