iOS底层学习-Day_04(KVO实现原理)
一、KVO(key-value observing)
KVO是OC对观察者模式(Observer Pattern)的实现。也是Cocoa Binding的基础。当被观察的某个属性发生更改时,观察者会获得通知。
二、KVO内部实现原理
、KVO是基于runtime机制实现的;
、当某个被观察对象的属性第一次被观察时,系统就会在运行时期间动态的创建一个派生类,该类派生继承自被观察对象的类,在这个派生类中重写基类中被观察属性的setter方法派生类在被重写的setter方法内调用NSObject的两个方法,willChangeValueForKey,和 didChangeValuekey;来实现真正的通知机制;
、如果原类为Person,那么生成的派生类名为NSKVONotifying_Person
、每个类对象中都有一个isa指针指向当前类,当被观察着对象第一次被观察,系统会通知runtime的object_setClass(被监听对象,新类的Class)方法将被观察者isa指针指向动态生成的派生类,从而在给被监控属性赋值时执行的是派生类的setter方法,但是你打印被观察对象的class的时候你会发现不是这个派生类的class,打印出来的还是原来的class,所以KVO机制为了掩盖这个派生类又重写了class方法,形如下面:
- (Class) class {
     // 得到类对象,在找到类对象父类
     return class_getSuperclass(object_getClass(self));
}
键值观察通知依赖于NSObject 的两个方法:
willChangeValueForKey::在一个被观察属性发生改变之前调用,这样就会记录旧的值。didChangevlueForKey::在改变发生后调用就会记录新的值,继而 会条用观察者中实现的observeValueForKey:ofObject:change:context:方法。
窥探person的KVO的方法
 * 1、利用RuntimeAPI动态生成一个子类,并且让instance对象的isa指向这个全新的子类
 * 2、当修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数
 * 3、willChangeValueForKey:
 * 4、父类原来的setter
 * 5、didChangeValueForKey:
 * 6、内部会触发监听器(Oberser)的监听方法(observeValueForKeyPath:ofObject:change:context:)
//NSKVONotifying_Person是使用runtime动态创建的一个类,是Person的字类,而且NSKVONotifying_Person子类的superclasss指向父类的Person
//self.person1.isa => NSKVONotifying_Person
[self.person1 setAge:20];
//self.person2.isa => Person
[self.person2 setAge:22];
NSKVONotifying_Person中的setAge方法
-(void)setAge:(int)age {
  _NSSetIntValueAndNotify();
}
void _NSSetIntValueAndNotify() {
  [self willChangeValueForKey:@"age"];
  [super setAge:age];
  [self didChangeValueForKey:@"age"];
}
-(void)didChangeValueForKey:(NSString*)key {
  // 通知监听器,某某属性值发生了改变
    [oberser observeValueForKeyPath:key ofObject:self change:nil context:nil];
}
                    
                
                
            
        
浙公网安备 33010602011771号