2013-01-20 106 views
1

在iOS文档中阅读KVC兼容时。我试图测试一个班级。 KVC Class是否合规?KVC兼容类

但我有一些问题:

  1. 没有setter方法的属性“姓名”,“年龄”,类仍然使用KVC没有错误 ,没有异常将被解雇

  2. 当没有为属性创建setter时,编译器会做什么? 是否创造了一对二传手和获得者?

    Person.h

    @interface Person : NSObject 
    { 
        NSString *name; 
        NSInteger age; 
    } 
    

    Person.m

    @implementation Person 
    
    - (id)init 
    { 
        self = [super init]; 
        if (self) { 
         name = @"Duc Nguyen"; 
         age = 10; 
        } 
        return self; 
    } 
    

    ViewController.m

    - (IBAction)showKeyKVC:(id)sender { 
        //--test kvc 
        name1.text = [person valueForKey:@"name"]; 
        age1.text = [NSString stringWithFormat:@"%@", [person valueForKey:@"age"]]; 
    } 
    

当我按下按钮的结果是:年龄:10,名称:Duc Nguyen。 我不明白在这种情况下班级如何使用KVC?

回答

4

答案在Accessor Search Patterns for Simple Attributes KVC指南。

为的setValue默认搜索模式:forKey:

setValue:forKey:默认实现被调用,使用下面的搜索模式的特性:

  1. 接收器的类中搜索一个名称与模式set<Key>:匹配的访问方法。
  2. 如果没有访问被发现,并accessInstanceVariablesDirectly返回YES接收器的类方法中,接收机中搜索实例变量,其名字的模式,_<key>_is<Key><key>,或is<Key>,按照这个顺序相匹配。

默认的实现是YES回到accessInstanceVariablesDirectly方法,所以KVC机制实际上是从nameage实例变量得到的值。

+3

因此,我强烈建议覆盖'+ accessInstanceVariablesDirectly'来为所有自定义类返回NO。 KVC直接访问实例变量的方式是一种可怕的封装和隐藏错误。 –