美文网首页
iOS KVC 复习

iOS KVC 复习

作者: 笔头还没烂 | 来源:发表于2023-04-17 23:33 被阅读0次
  1. KVC 的全称是 Key-Value Coding,俗称“键值编码”,可以通过一个 key 来访问某个属性

  2. 常见的 API 有:

    //设置值
    - (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
    - (void)setValue:(id)value forKey:(NSString *)key;
    //获取值
    - (id)valueForKeyPath:(NSString *)keyPath;
    - (id)valueForKey:(NSString *)key;
    
  3. 简单复习KVC的使用,示例代码如下:

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    @property (nonatomic,assign) int age;
    @end
    @implementation Person
    @end
    int main(int argc, char * argv[]) {
        @autoreleasepool {
            // Setup code that might create autoreleased objects goes here.
            Person *p = [[Person alloc] init];
    //        [p setValue:@10 forKey:@"age"];
            [p setValue:@10 forKeyPath:@"age"];
            NSLog(@"%d",p.age);
        }
        return 0;
    }
    

    输出结果如下:

    10

    • 在 iOS 的 KVC(Key-Value Coding) 中,setValue:forKey 和 setValue:forKeyPath 都可以完成属性的赋值操作,那他们的区别是什么呢?

      (1)setValue:forKey 是对某个对象的某个属性进行赋值,其中键是属性名。它只能访问到当前对象的继承体系中已定义的属性,而不能访问到动态添加的属性或成员变量;

      (2)setValue:forKeyPath 是使用一个点语法来指定属性的层级路径进行赋值操作。它除了可以访问当前对象的属性之外,还可以访问属性所嵌套的其他对象的属性,支持对嵌套属性进行递归赋值操作。例如,如果想给一个人对象(Person)的子对象(Address)的属性(city)进行赋值操作,可以使用 setValue:forKeyPath 来指定完整的路径“address.city”,而不需要一步步地访问到这个属性。

      需要注意的是,使用 KVC 进行属性赋值时,虽然可以通过键值编码的方式,简单地统一了属性和方法的访问,但是需要确保键名和键路径的正确性和安全性,避免破坏对象的内部状态并导致未知的错误。

  4. 相关问题

    • 通过 KVC 修改属性会触发 KVO 么?

      会触发 KVO。验证:可以重写类中的 willChangeValueForKey: 和 didChangeValueForKey: 这两个方法。可以发现,KVC 的赋值操作,底层在对成员变量赋值之前会调用 willChangeValueForKey: 的方法,然后对成员变量赋值;接着再调用 didChangeValueForKey: 方法。didChangeValueForKey: 方法内部会通知监听器调用监听方法。

    • KVC 的赋值和取值过程是怎么样的?原理是什么?

      (1)setValue:forKey: 的赋值原理如下:

      • 先判断是否存在 setKey: 、_setKey: 的方法,按此顺序查找方法,如果能找到,则直接传递参数,调用方法;
      • 如果找不到,则查看 accessInstanceVariablesDirectly 方法的返回值(该方法的返回值默认是返回YES),如果该方法的返回值是 no,则意味着不允许直接访问成员变量,此时程序直接抛出异常,会调用 setValue:forUndefinedKey: 方法;
      • 如果 accessInstanceVariablesDirectly 方法的返回值是 Yes,则会按照 _key、 _isKey、key、isKey 的顺序查找成员变量,如果能找到成员变量,则直接赋值;
      • 如果找不到成员变量,则程序抛出异常,会调用 setValue:forUndefinedKey: 方法;

      (2)valueForKey: 的取值过程原理如下:

      • 按照 getKey、key、isKey、_key 顺序查找方法。如果能找到了方法则直接调用方法;
      • 如果找不到,则查看 accessInstanceVariablesDirectly 方法的返回值(该方法的返回值默认是返回YES),如果该方法的返回值是 no,则意味着不允许直接访问成员变量,此时程序直接抛出异常,会调用NSUnknownKeyException;
      • 如果 accessInstanceVariablesDirectly 方法的返回值是 Yes,则会继续按照 _key、 _isKey、key、isKey 顺序查找成员变量。
      • 如果找不到成员变量,则程序抛出异常,会调用 setValue:forUndefinedKey: 方法;

相关文章

网友评论

      本文标题:iOS KVC 复习

      本文链接:https://www.haomeiwen.com/subject/uuchjdtx.html