kvc kvo

原文 kvc kvo

KVC 概论

KVC(全称 key-value-coding)即键值编码。KVC 的操作方法由NSKeyValueCoding 非正式协议提供,而NSObject(NSKeyValueCoding)就实现了这个协议,也就是说ObjC中几乎所有的对象都支持 KVC 操作,它是一种不通过存取方法(Setter、Getter),而通过属性名称字符串(key)间接访问类属性(实例变量)的机制。

- (void)setValue:(nullable id)value forKey:(NSString *)key;

- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;

- (id)valueForKey:(NSString *)key;

- (nullable id)valueForKeyPath:(NSString *)keyPath;


KVC 实现原理

1、[item setValue:@"白开水ln简书" forKey:@"name"];

1.首先去模型中查找有没有 setName,若有,直接调用赋值 [self setName:@"白开水ln简书"]。

2.若无,去模型中查找有没有 name 属性,若有,直接访问属性赋值 name = value。

3.若无,再去模型中查找有没有 _name 成员变量,若有,直接访问属性赋值 _name = value。

4.找不到,就会直接报找不到的错误(valueForUndefinedKey:)。


2、[item setValuesForKeysWithDictionary:dict];

1.遍历字典中所有 key。

2.去模型中查找有没有对应的属性。



LNPerson *person = [[LNPerson alloc] init];

person.dog = [[LNDog alloc] init];

[person.dog setValue:@"阿黄" forKey:@"name"];

[person setValue:@"旺财" forKeyPath:@"dog.name"];

NSLog(@"%@", person.dog.name);

区别:forKey: 和 forKeyPath:

1、forKeyPath 包含了所有 forKey 的功能

2、forKeyPath 进行内部的点语法,层层访问内部的属性

3、注意:key 值一定要在属性中找到,开发中最好使用forKeyPath。




KVO(Key-Value-Obersver)即键值监听,利用一个key来找到某个属性并监听其属性值得改变,当该属性发生变化时,会自动的通知观察者,这比通知中心需要post通知来说,简单了许多。其实这也是一种典型的观察者模式。

KVO 使用步骤

给目标对象的属性添加观察者

在回调方法中监听属性的变化

移除观察者

// 1.添加观察者

[self.person addObserver:self forKeyPath:@"name" options: NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];}

- (void)dealloc{

// 2.移除观察者

[self.person removeObserver:self forKeyPath:@"name"];

}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(LNPerson *)person change:(NSDictionary *)change context:(void *)context{

NSLog(@"%@------%@------%@", keyPath, change);

}

KVO 实现原理

当一个类的属性被观察的时候,系统会通过runtime动态的创建一个该类的派生类,而且系统将这个类的isa指针指向了派生类,从而实现了给监听的属性赋值时调用的是派生类的setter方法。

还会在这个类的基类中重写被观察的属性的setter方法,重写的setter方法会在调用原setter方法前后,通知观察对象值得改变

同时派生类还重写了 class 方法以“欺骗”外部调用者它就是起初的那个类。

此外,派生类还重写了 dealloc 方法来释放资源。

KVO 实现原理

可以看到重写的 setter 方法,给属性赋值的前后分别调用了两个方法。

- (void)willChangeValueForKey:(NSString *)key;

- (void)didChangeValueForKey:(NSString *)key;

而- (void)didChangeValueForKey:(NSString *)key;会调用

- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:(nullable void *)context;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • KCV 其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的动态读写,这种方式就是Key Value...
    TYM阅读 1,067评论 0 4
  • KVC KVC定义 KVC(Key-value coding)键值编码,就是指iOS的开发中,可以允许开发者通过K...
    暮年古稀ZC阅读 2,190评论 2 9
  • 作者:wangzz原文地址:http://blog.csdn.net/wzzvictory/article/det...
    反调唱唱阅读 1,124评论 0 5
  • 由于Objective-C是基于Smalltalk进行设计的,所以它具有动态加载、动态绑定等特性。Key-valu...
    赵亦晨阅读 1,101评论 0 0
  • KVC , KVO KVC和KVO的区别及应用 KVC/KVO原理 1. KVC键值编码 KVC,即是指NSKey...
    旋叶阅读 320评论 0 1