KVO简介
KVO
<Key-Value-Observing>顾名思义,键值监听,可以用于监听某个对象属性值的变化,做iOS开发的人应该相当了解。KVO
是一个非正式协议,提供了一个途径,使对象(观察者)能够观察其他对象(被观察者)的属性,当被观察者的属性发生变化时,观察者就会被告知该变化。首先了解一下KVO
的基本使用,然后在此基础上,我们深入了解一下KVO
的底层实现原理。
KVO的基本使用
KVO
的基本使用比较简单,主要用到两个方法:
//给一个对象属性添加KVO监听
[self addObserver:(nonnull NSObject *)
forKeyPath:(nonnull NSString *)
options:(NSKeyValueObservingOptions)
context:(nullable void *)]
//当监听对象的属性值发生改变时,就会调用
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context
当然,我们这片文章肯定不会这么简单的介绍KVO
的使用这么简单,我们需要深究一下KVO
在底层的实现。在了解KVO
底层之前,我们先要对isa
一些基本的概念有个了解,instance对象的isa指向class对象,class对象的isa指向Meta-Class对象,Meta-Class对象的isa指向基类的Meta-Class对象
。当然,这些都是基本的概念相信大家都知道。对使用了KVO
监听的对象,Runtime
会在底层动态的创建一个新的类,NSKVONotifying_A类
,这个类相当于A类的子类,即NSKVONotifying_A类
的superclass指向A类。如图
KVC简介
KVC
<Key-Value-Coding>顾名思义,键值编码,一个非正式的 Protocol,提供一种机制来间接访问对象的属性。常用API:
[self.person setValue:@10 forKey:@"age"];
[self.person setValue:@10 forKeyPath:@"age"];
[self.person valueForKey:@"age"];
[self.person valueForKeyPath:@"age"];
KVC
修改属性,一定是会出发KVO
的,这个我们用代码可以很容易的得到实验结果。因为setValue:forKey会按照setKey:、_setKey:顺序查找方法,如果找到方法,传递参数调用方法,如果没有找到方法,查看accessInstanceVariableDirectly方法的返回值,返回YES按照_key、_isKey、key、iskey顺序查找成员变量,找到的话直接赋值。如果返回NO,调用setValue:forUndefinedKey:并抛出异常NSUnknownKeyException
KVC
和KVO
是iOS开发中最常用的两种设计模式之一,如果想对iOS的底层由更多的了解,可以查看Apple的官方文档,有写的不对的地方希望大家指出,共同交流,共同进步。
网友评论