美文网首页
OC基础-KVC

OC基础-KVC

作者: 我是卖报的小行家 | 来源:发表于2021-03-03 15:45 被阅读0次

KVC:Key-Value-Coding,俗称“键值编码”,可以通过一个key来访问某个属性
常见的api:

//用来设置属性值
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKey:(NSString *)key;
//用来获取属性值
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForKey:(NSString *)key; 

setValue:forKey:是如何赋值的

当我们调用[person setValue:@10 forKey:@"age”];方法时,系统会依次做如下操作:
先查找Person类里面有没有setKey方法,如果没有则查找_setKey方法,如果查找到了就直接调用,如果都没有找到那么会调用accessInstanceVariablesDirectly方法,该方法是控制是否能访问成员变量,默认是返回YES,如果返回YES,则依次会查找Person类里面是否有_key,_isKey,key,isKey成员变量,如果有则赋值给它。如果都没有则抛出setValue:forUndefinedKey:异常。如果accessInstanceVariablesDirectly方法返回NO,也抛出setValue:forUndefinedKey:异常。

setValue:forKey整个过程

value:forKey:是如何取值的

当我们调用[person valueForKey:@"age"]方法时,跟上述方法类似,系统会依次做如下操作:
按顺序依次查找Person类里面有没有getKey,key,isKey,_key,如果有则直接调用方法,如果都没有找到,那么也会调用accessInstanceVariablesDirectly方法,该方法是控制是否能访问成员变量,默认是返回YES,如果返回YES,则依次会查找Person类里面是否有_key,_isKey,key,isKey成员变量,如果有则直接去成员变量的值,如果都没有则抛出setValue:forUndefinedKey:异常。如果accessInstanceVariablesDirectly方法返回NO,也抛出setValue:forUndefinedKey:异常。


value:forKey整个过程

如果我们用KVC给Person赋值,再给Person对象添加KVO,是否会触发KVO呢,答案是肯定的。
由以上可知当我们使用KVC对age赋值时,系统会去查找set方法,从而调用set方法,相当于set赋值所以肯定会触发KVO。
还有一种情况,如果没有找到set方法呢,比如下面这个Person类就没有set方法

@interface Person : NSObject
{
    @public
    int age;
}
@end

@implementation Person

@end

@interface MJObserver : NSObject

@end

@implementation MJObserver

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    NSLog(@"observeValueForKeyPath: %@",change);
}

@end

MJObserver *observer = [[MJObserver alloc] init];
        
Person *person = [[Person alloc] init];
        
//添加KVO监听
[person addObserver:observer forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
//尝试用KVC修改属性
[person setValue:@10 forKey:@"age"];
        
[person removeObserver:observer forKeyPath:@"age"];
打印:
2021-03-03 15:36:15.771458+0800 XMGTestProject[91287:6076018] observeValueForKeyPath: {
    kind = 1;
    new = 10;
    old = 0;
}

从代码实践中可以看出也触发了KVO,从上一篇KVO的本质中知道,没有set方法但是触发了KVO说明是手动调用了willChangeValueForKey和didChangeValueForKey方法,从而触发了KVO。也就是说:

[person setValue:@10 forKey:@"age"];
相当于以下三行代码
[person willChangeValueForKey:@"age"];
person->age = 10;
 [person didChangeValueForKey:@"age"];

通过KVC修改属性会触发KVO,尽管没有setter方法,但是[person setValue:@10 forKey:@"age”];内部会调用willChangeValueForKey和didChangeValueForKey方法,相当于手动触发了KVO。

相关文章

  • [OC基础]KVC

    key-value coding,使用字符串更改对象状态 介绍 用途:1.访问私有属性2.整体操作(计算)3.批处...

  • OC基础-KVC

    KVC:Key-Value-Coding,俗称“键值编码”,可以通过一个key来访问某个属性常见的api: set...

  • iOS面试分享

    OC基础 1.kvo、kvc原理2.runtime、runloop 应用场景3.GCD NSOperation N...

  • KVC-NSKeyValueCoding

    KVC作为OC中重要的编程思想、在很多场景下我们都会使用,也是开发者必须掌握的基础知识。那么什么是KVC,他的实现...

  • OC基础-(四)KVC、KVO

    KVO Q: 什么是KVO? KVO(key-value observing),从名称上就可以知道这是一种键值观察...

  • KVC

    今天和大家讨论一下OC中KVC(KeyValueCoding)键值编码 KVC定义 KVC(KeyValueCod...

  • KVC&KVO

    KVC Key value coding 键值对编程OC中KVC相关方法都放在NSKeyValueCoding类别...

  • iOS KVC

    OC底层学习笔记(4)-KVC - 简书

  • swift kvc 构造函数

    kvc 是oc特有 ,KVC 本质上是在运行时,直接调用程序会崩溃 介绍 kvc 构造函数 kvc构造函数的作用是...

  • Swift 基础之KVC 字典转模型构造函数

    KVC 字典转模型构造函数 以上代码编译就会报错! 原因:KVC 是 OC 特有的,KVC 本质上是在运行时,动态...

网友评论

      本文标题:OC基础-KVC

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