zoukankan      html  css  js  c++  java
  • iOS学习笔记8 KVO与KVC

    KVO和KVC分别是Key-Value Observing和Key-Value Coding的简称。想到这个话题是因为现在我写的tableView的更新是每隔数秒的轮询,在考虑是不是需要用个类似触发更新的机制。这自然就想到了观察者模式。

    搜索Objective-c的观察者模式,发现在http://stackoverflow.com/questions/165790/whats-the-nicest-way-to-do-observer-observable-in-objective-c-iphone-version 中提到有两种方式可以实现:NSNotificationCenter和KVO。那个回答里形容Notification是较为古老而重型的。。。虽然我也稍微研究过,不过还是作为下次的话题吧。 

     

    1. KVC

    咦,不是要说KVO吗?为什么先要说KVC?Mac Developer Library说KVC是KVO的准备知识。好吧,先来看看KVC。

    KVC是一种非直接访问对象属性的机制。什么是直接访问?get和set。

    用省略过头的话来解释,KVC就是通过key来获取value。

    有点像Dictionary?嗯,从某种意义上来说是,但远远不止。

    在Objective-C下,也有一个字典类NSDictionary,可以通过objectForKey方法来获取某个key所对应的value。但KVC可以在所有类中使用valueForKey这个方法,来获取某个property(key)的值(value)。

    来看看代码范例。例如有这么一个类:

    @interface TestClass : NSObject
    @property NSInteger integerProperty;
    @property TestClass *linkedInstance;
    @end

    可以使用传统的set来赋值,例如:

        TestClass *anotherInstance = [[TestClassalloc] init];
    
        myInstance.linkedInstance = anotherInstance;
    
        myInstance.integerProperty = 2;

    不过也可以用kvc来赋值:

        TestClass *anotherInstance = [[TestClass alloc] init];
    
        myInstance.linkedInstance = anotherInstance;
    
        [myInstance setValue:@2forKeyPath:@"linkedInstance.integerProperty"];

    从这个角度上来说,KVC类似于.NET中反射的部分功能。

    如上所述,要通过KVC取值,可以通过valueForKey。

    由于是语言级别的功能,所以KVC能实现的功能挺强大。例如:

    根据index来获取一个或数个:objectAtIndex, objectsAtIndexes, count, -get<Key>:range:

    增删改:insertObject, insertObjects,removeObjectAtIndex, replaceObjectAtIndex, 

     

    2. KVO

    KVO的作用是允许某个对象得知其他对象的某个属性发生了改动。在MVC的model和controller层之间的交互中应用得特别广泛。

    实现KVO需要三步:

    1) 明确通知对象和被通知对象

    例如:如果存款发生了变更,比如被提取了5000元,那么账户所有人就需要被告知。这个场景中,通知对象就是银行账户,被通知对象就是账户所有人

     

    2) 被通知对象在通知对象中,注册对某个属性的观察者

    语法为:addObserver:forKeyPath:options:context:

    对于上面那个例子,所有者就需要在账户实例里注册一个观察者。

    代码范例:

    [account addObserver:inspector

                  forKeyPath:@"openingBalance"

                     options:(NSKeyValueObservingOptionNew |

                              NSKeyValueObservingOptionOld)

                     context:NULL];

    其中option的参数表示需要得知这个属性更改前和更改后的值。

    另外,可以添加,自然也可以用removeObserver移除。

     

    3) 被通知对象(观察者)实现observeValueForKeyPath方法

    这个方法是用来实现当被通知后,观察者会做些啥反应

    对于上面那个例子,如果观察者判断自己有没有进行过提款或购物操作,然后决定是不是报警?

    代码范例:

    - (void)observeValueForKeyPath:(NSString *)keyPath
                          ofObject:(id)object
                            change:(NSDictionary *)change
                           context:(void *)context {
        if ([keyPath isEqual:@"openingBalance"]) {
            [openingBalanceInspectorField setObjectValue:
             [change objectForKey:NSKeyValueChangeNewKey]];
        }
        /*
         Be sure to call the superclass's implementation *if it implements it*.
         NSObject does not implement the method.
         */
        [superobserveValueForKeyPath:keyPath
                             ofObject:object
                               change:change
                              context:context];
    }

     

    参考资料:

    Key-Value Coding Programming Guide

    https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html%23//apple_ref/doc/uid/10000107-SW1

     

    Key-Value Observing Programming Guide

    http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html%23//apple_ref/doc/uid/10000177-BCICJDHA

  • 相关阅读:
    vb.net与XML之间的操作
    C#动态生成WORD文档并进行操作。
    Excel的VBA连接数据库方法
    C#动态生成EXCLE并进行添加内容
    c#与WORD之间的基本操作
    C#运用ADO.net动态创建excle并进行相应的数据修改显示
    USACOMother's Milk
    USACOArithmetic Progressions
    USACONumber Triangles
    USACOMilking Cows
  • 原文地址:https://www.cnblogs.com/galaxyyao/p/3134408.html
Copyright © 2011-2022 走看看