zoukankan      html  css  js  c++  java
  • 从[id setValue: forKey:]了解KVC


    《Objective-C基础教程》 P224页有详细介绍

    下边是apple官网的简单介绍 和一个应用的例子。


    KVC就是Key-value coding,大意是允许通过一个Key来读写一个value。

    最最常见就是

    [id setValue: forKey:]

    [id  valueforKey:]

    这两个方法允许你指定一个Key,然后通过这个Key去访问指定对象中的value


    1. [obj  valueforKey:@"name"];          //=>返回:在指定的对象里(obj),去查找名为“name”的实例变量的数值  
    2. [obj  setValue:@"target" forKey:@"name"]    //=>在obj中,将名为name的实例变量的数值,更换为“target”  


    KVC是去调用@synthesize,所以对应的name应该是名为name或_name的实例变量才对






    和键-值编码方法一样,自动的键-值观察将遵循键-值的访问器作出的变更通知给观察者。表1中的例子可实现当属性name发生变更时,其所有观察者都收到变更通知。

    表1 调用键-值观察的方法

    // calling the accessor method
    [self setName:@"Savings"];
     
    // using setValue:forKey:
    [self setValue:@"Savings" forKey:@"name"];
     
    // using a key path, where account is a kvc-compliant property
    // of "document"
    [document setValue:@"Savings" forKeyPath:@"account.name"]

    自动通知还支持mutableArrayValueForKey:mutableSetValueForKey:返回集合代理对象。这个功能可用于支持insertObject:in<Key>AtIndex:replaceObjectIn<Key>AtIndex:removeObjectFrom<Key>AtIndex:等索引存取方法的对多关系。

    你可以通过实现类方法automaticallyNotifiesObserversForKey:来控制你的子类的自动观察通知 。子类可以检测参数检测的键值,并在自动通知可用时返回YES ,禁用时则返回NO








    Key-value coding(KVC)机制允许set(设置)和get(获取)变量值。这里的变量名可能是一个字符串,也就是Key。   例如,类Company拥有一个类型为NSString,叫做companyName的变量。  

    @interface Company : NSObject
    {
        NSString *companyName;
    }
     我们就可以这样设置和获取Company实例的companyName值: 

    //设置值
    Company *company = [[Company alloc] init];
    [company setValue:@"Apple" forkey:@"companyName"];
     
    //获取值
    NSString *x = [company valueForKey:@"companyName"];
     setValue:forKey和valueForKey:的方法在NSObject中有定义。实例 创建名为KVCFun的项目,新建名为AppController的Objective-C Class文件。 AppController.h和AppController.m的代码分别如下: 

    #import <Foundation/Foundation.h>
     
    @interface AppController : NSObject {
    @private
        int fido;
     
    }
     
    - (int) fido;
    - (void) setFido:(int) x;
     
    - (IBAction) incrementFido: (id)sender;
     
    @end
     

    #import "AppController.h"
     
     
    @implementation AppController
     
    - (id)init
    {
        self = [super init];
        if (self) {
            //设置Key
            [self setValue:[NSNumber numberWithInt:5]
                    forKey:@"fido"];
     
            NSNumber *n = [self valueForKey:@"fido"];
            NSLog(@"fido = %@", n);
     
        }
     
        return self;
    }
     
    - (int) fido
    {
        NSLog(@"-fido is returning %d", fido);
        return fido;
    }
     
    - (void) setFido:(int) x
    {
        NSLog(@"-setFido is called with %d", x);
        fido = x;
    }
     
    - (IBAction) incrementFido:(id)sender
    {
        //当直接修改值时,通知观察者
        [self willChangeValueForKey:@"fido"];
        fido++;
        NSLog(@"fido is now %d", fido);
        [self didChangeValueForKey:@"fido"];
    }
     
    - (void)dealloc
    {
        [super dealloc];
    }
     
    @end
     打开MainMenu.nib,添加一个Slider、一个Label、一个Button控件,如下图:  将Slider的Attributes Inspector->Control->State设为“连续的”,再把Binding Inspector->value邦定到AppController实例的fido key上。 将Label也邦定到AppController上,Model Key Path设为fido。 Button链接到incrementFido:action上。  @property和@synthesize 我们可以使用property来代替fido和setFido,并且使用synthesize来实现存取方法。 
    使用下面的代码替换AppController.h中的fido和setFido: 

    @property (readwrite, assign) int fido;
     使用@synthesize来替换fido和setFido,程序可以正常运行。

  • 相关阅读:
    C#学习之委托和事件
    ArcGIS许可启动问题
    空间插值——克里金插值
    maven 问题解决 tools以及jconsole两个jar包 无效
    JDBC代码示例
    mysql 同一IP 产生太多终端的数据库连接导致阻塞
    apache 反向代理配置
    oracle、mysql、sql server等;流行数据库的链接驱动配置
    POI XSSF与HSSF的 使用区别
    使用IDEA开发Activiti工作流
  • 原文地址:https://www.cnblogs.com/zsw-1993/p/4879562.html
Copyright © 2011-2022 走看看