iOS KVO原理分析

通过断点可以看到已经被监听的类的isa指针:

(lldb) p self.person->isa
(Class) $0 = NSKVONotifying_WPPerson

问题是NSKVONotifying_WPPerson何时来的,我尝试在添加监听之前还有之后分别打印NSClassFromString(@"NSKVONotifying_WPPerson")发现NSKVONotifying_WPPerson是在添加观察者之后被创建的.

通过打印NSKVONotifying_WPPerson这个类的方法列表:

- (void)printMethods:(Class)class{
    unsigned int count = 0;
    Method *methods = class_copyMethodList(class, &count);
    for (int i = 0; i < count; i++) {
        Method method = methods[i];
        SEL sel = method_getName(method);
        IMP imp = method_getImplementation(method);
        NSString *methodName = NSStringFromSelector(sel);
        NSLog(@"%@",methodName);
    }
}

2019-01-14 16:11:27.591359+0800 KVO_learn[35003:466572] setArray:
2019-01-14 16:11:36.150872+0800 KVO_learn[35003:466572] class
2019-01-14 16:11:40.639886+0800 KVO_learn[35003:466572] dealloc
2019-01-14 16:22:35.932556+0800 KVO_learn[35003:466572] _isKVOA

断点发现IMP都是指向Foundition框架的

一般的内部执行过程是:

NSKeyValueWillChange
[WPPerson setSteps:]
NSKeyValueDIdChange
NSKeyValueNotifyObserver
observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change
主要注意的是移除观察者时:

1:移除之后isa指针指向了WPPerson
2:但是NSKVONotifying_WPPerson这个类已经被注册过了,不会被销毁,只是ISA指针改变了

你可能感兴趣的:(iOS KVO原理分析)