iOS原理(二)----KVO,KVC

2018-12-27  本文已影响0人  会笑的Even

iOS原理(二)----KVO,KVC

KVO

KVO的全称是Key-Value Observing,俗称“键值监听”,可以用于监听某个对象属性值的改变.下面是一个简单实用KVO的例子:

@interface Animal : NSObject

@property (nonatomic,assign) int age;

@end

@implementation Animal

@end


- (void)viewDidLoad {
    [super viewDidLoad];
    
     self.ani = [[Animal alloc] init];
    self.ani.age = 10;
    [self.ani addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
    

}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.ani.age = 20;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"%@---%@---%@",keyPath,object,change);
}

通过断点发现添加KVO后,对象的isa指针变为NSKVONotifying_Animal,

Snip20181109_16.png

setAge实际调用为:NSSetIntValueAndNotify

Snip20181109_17.png

大概实现为:

didChangeValueForKey:内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法.

KVO动态生成的类,还会重写class,dealloc,_isKVOA等.调用class方法,会得到原来的类对象,对外封装实现细节.

所以KVO的本质为:利用RuntimeAPI动态生成一个子类,并且让instance对象的isa指向这个全新的子类,当修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数,然后依次调用willChangeValueForKey,父类原来的setter和didChangeValueForKey(内部会触发监听器(Oberser)的监听方法( observeValueForKeyPath:ofObject:change:context:)).

当对象值没有改变时,我们任然要触发KVO时,我们可以手动触发KVO:手动调用willChangeValueForKey:和didChangeValueForKey.直接修改成员变量的值不会触发KVO.

KVC

KVC的全称是Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性
.

setValue:forKey:的原理:

valueForKey:的原理:

KVC会自动触发KVO.

上一篇 下一篇

猜你喜欢

热点阅读