KVO的实现原理探寻

时间:2023-03-09 08:31:10
KVO的实现原理探寻

@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

一讲到KVO好像很神奇很厉害的样子,那究竟是什么原理呢

首先,我们先来见一个最简单的KVO

新建一个Person类,就一行代码

@property (nonatomic, assign) int age;

然后在viewController中调用一下

- (void)viewDidLoad {

[super viewDidLoad];

_p = [[Person alloc] init];

_p.age = 10;

[_p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];

_p.age = 20;

}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

NSLog(@"%@对象的%@属性改变:%@", object, keyPath, change);

}

- (void)dealloc

{

[_p removeObserver:self forKeyPath:@"age"];

}

输出结果:

<Person: 0x7f7fcb6678e0>对象的age属性改变:{

    kind = 1;

    new = 20;

    old = 10;

}

下面进入正题,我们打两个断点调试一下

KVO的实现原理探寻

第一个断点给age赋值的时候,P的isa指针指向的是Preson,说明是Person类

KVO的实现原理探寻

当增加完监听以后,神奇的事情发生了,P的isa指针指向了NSKVONotifying_Person,显然我们是没有创建过这个类的,

那一定是自动创建的了

KVO的实现原理探寻

然后我们打印一下setAge地址看看:

NSLog(@"%p",method_getImplementation(class_getInstanceMethod(objc_getClass("Person"), @selector(setAge:))));

NSLog(@"%p",method_getDescription(class_getInstanceMethod(objc_getClass("NSKVONotifying_Person"), @selector(setAge:))));

输出结果 ;

 0x103ffb9a0

 0x7fddaa69fe58

总结:过多的就不探寻了,推测应该是系统自动创建了一个 NSKVONotifying_Person 类继承自 Person,并重写了set方法,这样就能够知道什么时候键值发生了改变

@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);