• KVC & KVO


      KVC和KVO看上去又是两个挺牛的单词简写,KVC是Key-Value Coding的简写,是键值编码的意思。KVO是Key-Value  Observing的简写,是键值观察的意思。那么我们能拿KVC和KVO干些什么事呢?这两个缩写单词不能否认听起来挺高端的样子。这两个方法都是runtime方法,我们先来介绍KVC。

            1.KVC(Key-Value Coding)键值编码

                为了测试我们建立两个测试类

                      测试类一:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #import <Foundation/Foundation.h>
    @class SubKVCClass;
    @interface KVCClass : NSObject
    @property(copy ,nonatomic) NSString *name;
    @property(retain, nonatomic) SubKVCClass *subKVC;
    @end
     
     
    #import "KVCClass.h"
    #import "SubKVCClass.h"
     
    @implementation KVCClass
    -(NSString *)description
    {
        NSString *str = [NSString stringWithFormat:@"property = %@, subName = %@", _name, _subKVC.subName];
        return str;
    }
     
    @end

                    测试类二:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #import <Foundation/Foundation.h>
    @interface SubKVCClass : NSObject
    @property (copy, nonatomic) NSString *subName;
    @end
     
     
    #import "SubKVCClass.h"
    @implementation SubKVCClass
    @end

                (1)我们可以用键值编码给对象的属性动态赋值(必须得有标准的getter和setter方法,或者用@property声明)

                    我们可以调用setValue: forKey: 方法以字符串的相识向对象发送消息,可以设置实例变量的值。第一个参数是要设置的值,第二个参数是实例变量的名称

                    我们可以调用valueForKey: 来获取实例变量的值,废话少说,代码走起:

    1
    2
    3
    4
    5
    KVCClass *kvc = [KVCClass new];
    //通过setValue: forKey:来动态设置属性的值
    [kvc setValue:@"我是同过setValue方法设置的值" forKey:@"name"];
    //通过valueForkey来获取值
    NSLog(@"name = %@", [kvc valueForKey:@"name"]);

                代码运行结果:

    1
    2014-08-14 16:08:57.940 Memory[1414:303] name = 我是同过setValue方法设置的值

                (2)我们可以通过键路径给实例变量是其他类的对象赋值 setValue: forKeyPath:

                    代码如下: 接着上面的代码来得,KVC的一项实例变量是SubKVCClass的对象

    1
    2
    3
    4
    5
    6
    //通过键路径来给KVCClass中的对象的属性赋值
    SubKVCClass *sub = [SubKVCClass new];
    kvc.subKVC = sub;  
    [kvc setValue:@"我是subName, 通过kvc的键路径来给我赋的值" forKeyPath:@"subKVC.subName"];
    NSLog(@"subName = %@", [kvc valueForKeyPath:@"subKVC.subName"]);
    NSLog(@"%@", kvc);

                上面代码的运行结果:

    1
    2
    2014-08-14 16:08:57.941 Memory[1414:303] subName = 我是subName, 通过kvc的键路径来给我赋的值
    2014-08-14 16:08:57.942 Memory[1414:303] property = 我是同过setValue方法设置的值, subName = 我是subName, 通过kvc的键路径来给我赋的值

            KVC的基本内容概就这些吧,当然啦还有在数组中使用KVC以及KVC中的运算-集合等,不做赘述啦。

        2.介绍完KVC那么我们来介绍一下KVO,键值观察

            键值观察是个什么东西啊?他有什么用啊?怎么用?从字面意思上说键值观察就是观察属性值的变化,也是运行时的方法,当实例变量改变时,系统会自动采取一些动作。

            KVO使用三步走:

                 (1)注册成为观察者

                 (2)观察者定义KVO的回调

                 (3)移除观察者

            来点实际的,还得上代码:

            KVOClass接口:

    1
    2
    3
    4
    5
    #import <Foundation/Foundation.h>
     
    @interface KVOClass : NSObject
    @property(strong,nonatomic) NSString * name;
    @end

             

           KVOClass实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #import "KVOClass.h"
     
    @implementation KVOClass
    //在init注册观察者
    -(id) init
    {
        if (self = [super init]) {
            [self addObserver:self
                   forKeyPath:@"name"
                      options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                      context:@"name"];
        }
        return self;
    }
     
    //重写观察方
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        if (context == @"name") {
            NSLog(@"name被改变啦!");
        else {
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }
    //移除观察者
    -(void) dealloc
    {
        [self removeObserver:self forKeyPath:@"name"];
        [super dealloc];
    }
    @end

        ​代码说明:注册观察者的时候调用addObserver方法,第一个参数是观察那个类,第二个参数是那个类中的那个属性,第三个方法是观察选项,第四个会传到下面的观察方法中

        ​  上面的代码运行结果为:

    1
    2014-08-14 16:56:16.843 Memory[1483:303] name被改变啦!

     

  • 相关阅读:
    无锁队列的实现 | 酷壳 CoolShell.cn
    简明 Vim 练级攻略 | 酷壳 CoolShell.cn
    分享:lucene 的评分机制
    JS实现面向对象的设计
    EF架构~性能高效的批量操作(Update篇)
    将不确定变为确定~transactionscope何时提升为分布式事务?
    将不确定变为确定~Linq to SQL不能随机排序吗?
    vs2012~ 开发人员的福音
    白领职场必懂的22条潜规则(转载)
    经典面试题(转载)
  • 原文地址:https://www.cnblogs.com/zhangkeyu/p/6659431.html
Copyright © 2020-2023  润新知