KVC和KVO
2016-08-26 本文已影响15人
奕十八
ngnmg
KVC底层实现
- 当一个对象调用setValue方法,方法内部会做以下操作:
- 检查是否存在相应key的set方法,如果有就调用
- 如果没有就查看有没有与key同名并且带下划线的属性,如果有就直接赋值。
- 如果没有,就继续查看有没有与key同名不带下划线的属性,如果有就直接赋值
- 如果还是没有找到,就调用setValue:forUndefinedKey:方法
KVO底层实现
-
kvo基于runtime机制实现,使用了isa混写,当一个对象(假设是person对象,person对象的类是MYPerson类)的属性值发生变化时,系统会自动产生一个类继承自MYPerson:NSKVONotifying_MYPerosn,在这个类的setAge方法里面,调用[super setAge:age] [self willChangeValueForKey:@"age"] 和[self
didChangeValueForKey:@"age"],这两个方法会调用 automaticallyNotifiesObserversForKey -
同时派生类还重写了 class 方法以“欺骗”外部调用者它就是起初的那个类。然后系统将这个对象的 isa 指针指向这个新诞生的派生类,因此这个对象就成为该派生类的对象了,因而在该对象上对 setter 的调用就会调用重写的 setter,从而激活键值通知机制。此外,派生类还重写了 dealloc 方法来释放资源。
KVO的优缺点
-
优点
- 能够提供一种简便的方法来实现两个对象之间的同步
- 能够对非我们创建的对象,即内部对象的状态改变做出响应,而且不需要改变内部对象的实现
- 能够提供观察的属性的新值以及先前值
-
缺点
- 我们观察的属性必须使用string来定义,因此在编译器不会出现警告以及检查
- 对属性进行重构将会导致我们的观察代码不可再用
- 当释放观察者需要移除观察者