通過斷點可以看到已經(jīng)被監(jiān)聽的類的isa指針:
(lldb) p self.person->isa
(Class) $0 = NSKVONotifying_WPPerson
問題是NSKVONotifying_WPPerson何時來的,我嘗試在添加監(jiān)聽之前還有之后分別打印NSClassFromString(@"NSKVONotifying_WPPerson")發(fā)現(xiàn)NSKVONotifying_WPPerson是在添加觀察者之后被創(chuàng)建的.
通過打印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
斷點發(fā)現(xiàn)IMP都是指向Foundition框架的
一般的內(nèi)部執(zhí)行過程是:
NSKeyValueWillChange
[WPPerson setSteps:]
NSKeyValueDIdChange
NSKeyValueNotifyObserver
observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change
主要注意的是移除觀察者時:
1:移除之后isa指針指向了WPPerson
2:但是NSKVONotifying_WPPerson這個類已經(jīng)被注冊過了,不會被銷毀,只是ISA指針改變了