从添加观察者开始
[_p addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
通过Hopper反编译得到addObserver:forKeyPath的实现
/* @class NSObject */
-(void)addObserver:(void *)arg2 forKeyPath:(void *)arg3 options:(unsigned long long)arg4 context:(void *)arg5 {
os_unfair_recursive_lock_lock_with_options(__NSKeyValueObserverRegistrationLock.llvm.18255262684423441536, 0x0, arg2, arg3, arg4, arg5);
[self _addObserver:arg2 forProperty:_NSKeyValuePropertyForIsaAndKeyPath(object_getClass(self), arg3) options:arg4 context:arg5];
os_unfair_recursive_lock_unlock(__NSKeyValueObserverRegistrationLock.llvm.18255262684423441536);
return;
}
加锁,解锁不用说。中间的这句调用了两个方法:
[self _addObserver:arg2 forProperty:_NSKeyValuePropertyForIsaAndKeyPath(object_getClass(self), arg3) options:arg4 context:arg5];
1._NSKeyValuePropertyForIsaAndKeyPath
2._addObserver:forProperty:
int _NSKeyValuePropertyForIsaAndKeyPath(int arg0, int arg1) {
r14 = rsi;
r15 = rdi;
__NSKeyValueContainerClassForIsa();
if (*_NSKeyValueProperties.llvm.13863498383568664478 != 0x0) {
stack[-80] = 0x0;
rax = CFSetGetValue(*_NSKeyValueProperties.llvm.13863498383568664478, &stack[-80]);
rbx = rax;
if (rax == 0x0) {
rax = *_kCFTypeSetCallBacks;
*(&stack[-128] + 0x18) = *(rax + 0x18);
*(&stack[-128] + 0x10) = *(rax + 0x10);
rcx = *rax;
*(&stack[-128] + 0x8) = *(rax + 0x8);
stack[-128] = rcx;
*(&stack[-128] + 0x20) = _NSKeyValuePropertyIsEqual.llvm.13863498383568664478;
*(&stack[-128] + 0x28) = _NSKeyValuePropertyHash.llvm.13863498383568664478;
rax = CFSetCreateMutable(0x0, 0x0, &stack[-128]);
rbx = _NSKeyValuePropertyForIsaAndKeyPathInner.llvm.13863498383568664478(r15, r14, rax);
CFRelease(rax);
if (0x0 == 0x0) {
if (**___stack_chk_guard == **___stack_chk_guard) {
rax = rbx;
}
else {
rax = __stack_chk_fail();
}
}
else {
rax = objc_exception_rethrow();
}
}
else {
if (**___stack_chk_guard == **___stack_chk_guard) {
rax = rbx;
}
else {
rax = __stack_chk_fail();
}
}
}
else {
rax = *_kCFTypeSetCallBacks;
*(&stack[-128] + 0x18) = *(rax + 0x18);
*(&stack[-128] + 0x10) = *(rax + 0x10);
rcx = *rax;
*(&stack[-128] + 0x8) = *(rax + 0x8);
stack[-128] = rcx;
*(&stack[-128] + 0x20) = _NSKeyValuePropertyIsEqual.llvm.13863498383568664478;
*(&stack[-128] + 0x28) = _NSKeyValuePropertyHash.llvm.13863498383568664478;
rax = CFSetCreateMutable(0x0, 0x0, &stack[-128]);
rbx = _NSKeyValuePropertyForIsaAndKeyPathInner.llvm.13863498383568664478(r15, r14, rax);
CFRelease(rax);
if (0x0 == 0x0) {
if (**___stack_chk_guard == **___stack_chk_guard) {
rax = rbx;
}
else {
rax = __stack_chk_fail();
}
}
else {
rax = objc_exception_rethrow();
}
}
return rax;
}
int __NSKeyValueContainerClassForIsa(int arg0, int arg1, int arg2) {
rdi = arg0;
if (*0x4c29c0 != rdi) {
r15 = rdi;
r14 = __NSKVONotifyingOriginalClassForIsa(rdi);
if (*0x4c29d0 != 0x0) {
//获取原来的类
rax = CFDictionaryGetValue(*0x4c29d0, r14);
rbx = rax;
if (rax == 0x0) {
//创建中间类
rax = [NSKeyValueContainerClass alloc];
rax = [rax initWithOriginalClass:r14];
rbx = rax;
CFDictionarySetValue(*0x4c29d0, r14, rax);
[rbx release];
}
}
else {
*0x4c29d0 = CFDictionaryCreateMutable(0x0, 0x0, 0x0, *_kCFTypeDictionaryValueCallBacks);
rax = [NSKeyValueContainerClass alloc];
rax = [rax initWithOriginalClass:r14];
rbx = rax;
CFDictionarySetValue(*0x4c29d0, r14, rax);
[rbx release];
}
*0x4c29c0 = r15;
*0x4c29c8 = rbx;
}
else {
rbx = *0x4c29c8;
}
rax = rbx;
return rax;
}
/* @class NSKeyValueContainerClass */
-(void *)initWithOriginalClass:(void *)arg2 {
r14 = arg2;
var_38 = self;
*(&var_38 + 0x8) = *0x4ace20;
rax = [[&var_38 super] init];
rbx = rax;
if (rax != 0x0) {
*(rbx + 0x8) = r14;
//observationInfo这个属性中存储有属性的监听者,监听的keyPath,通知者,等
//是公开api
//调用方法id a = self.p.observationInfo;
*(rbx + 0x10) = class_getMethodImplementation(r14, sel_registerName("observationInfo"));
r14 = *(rbx + 0x8);
rax = sel_registerName("setObservationInfo:");
rax = class_getInstanceMethod(r14, rax);
*(rbx + 0x18) = method_getImplementation(rax);
method_getArgumentType(rax, 0x2, &var_21, 0x1);
if (var_21 == 0x40) {
*(int8_t *)(rbx + 0x20) = 0x1;
}
}
if (**___stack_chk_guard == **___stack_chk_guard) {
rax = rbx;
}
else {
rax = __stack_chk_fail();
}
return rax;
}
通过打印observationInfo这个属性 可以得到:监听者,监听的keyPath,通知者,
同一属性给同一个观察者添加两次就会出现两个相同的。
查看setObservationInfo源码
/* @class NSObject */
-(void)setObservationInfo:(void *)arg2 {
r14 = arg2;
rbx = self;
rdi = *_NSKeyValueObservationInfoPerObject.llvm.18255262684423441536;
if (rdi == 0x0) {
rax = CFDictionaryCreateMutable(0x0, 0x0, 0x0, 0x0);
rdi = rax;
*_NSKeyValueObservationInfoPerObject.llvm.18255262684423441536 = rax;
}
rsi = !rbx;
if (r14 != 0x0) {
CFDictionarySetValue(rdi, rsi, r14);
}
else {
CFDictionaryRemoveValue(rdi, rsi);
}
return;
}
鸣谢