obj->isa可以使用object_getClass(obj)进行获取
修改obj的isa指针, 可通过object_setClass(id obj, Class cls) 方法进行实现
** 注意:objc_msgSend调用时报错,设置Build Settings -> Enable Strict Checking of objc_msgSend Calls 为 NO **
KVO如何访问属性值
- 检查是否存在-、-is(只针对布尔值有效)或者-get的访问器方法,如果有可能,就是用这些方法返回值;检查是否存在名为-set:的方法,并使用它做设置值。对于-get和-set:方法,将大写Key字符串的第一个字母,并与Cocoa的方法命名保持一致;
- 如果上述方法不可用,则检查名为-_、-_is(只针对布尔值有效)、-_get和-_set:方法;
- 如果没有找到访问器方法,可以尝试直接访问实例变量(
ivar)。实例变量可以是名为:或_; - 如果仍为找到,则调用valueForUndefinedKey:和setValue:forUndefinedKey:方法。这些方法的默认实现都是抛出异常,我们可以根据需要重写它们。
KVO实现原理
当观察某对象A时,KVO机制动态创建一个对象A当前类的子类(NSKVONotifying_A),NSKVONotifying_A中重写了以下几个方法。
- setter方法。重写setter方法,并为这个新的子类重写了被观察属性keyPath的setter 方法。setter 方法随后负责通知观察对象属性的改变状况。
- class方法,实现返回父类A,类似
- (Class) class {return class_getSuperclass(object_getClass(self));} - dealloc方法
- _isKVOA方法,用于标识该类是否为KVO运行时动态生成的类。
更重要的是KVO修改了被监听对象的isa指针。