KVO底层伪代码

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context {
    DSKeyValueProperty * property = DSKeyValuePropertyForIsaAndKeyPath(object_getClass(self),keyPath);
    Class isaForAutonotifying = [property isaForAutonotifying];
    if(isaForAutonotifying) {
        Class cls = object_getClass(self);
        // 把当前类的isa指向动态创建的子类
        if(cls != isaForAutonotifying) {
            object_setClass(self,isaForAutonotifying);
        }
    }
}

- (Class)isaForAutonotifying {
    // 动态创建一个子类
    Class subClass = objc_allocateClassPair(originalClass, newClassName, sizeof(DSKeyValueNotifyingInfo));
    objc_registerClassPair(subClass);
    // 为子类添加四个方法
    class_addMethod(subClass, @selector(_isKVOA), NSKVOIsAutonotifying, encoding);
    class_addMethod(subClass, @selector(dealloc), NSKVODeallocate, encoding);
    class_addMethod(subClass, @selector(class), NSKVOClass, encoding);
    class_addMethod(subClass, @selector(setXXX), _NSSetObjectValueAndNotify, encoding);
    return subClass;
}

Class NSKVOClass(id object, SEL selector) {
    // 返回调用父类的class方法
    return [originalClass class];
}

void _NSSetObjectValueAndNotify(id object,SEL selector, id value) {
    NSKeyValueWillChange();
    // keypath嵌套的情况下调用下面两句
    [changingRelationshipObject removeObserver:observance forKeyPath:_keyPathFromRelatedObject];        
    [newRelationshipObject addObserver:observance forKeyPath:_keyPathFromRelatedObject options:option context:context];
    // 调用父类的setter
    IMP imp = class_getMethodImplementation(info->originalClass, selector);
    setValueWithImplementation(imp);
    NSKeyValueDidChange();
}

void NSKeyValueDidChange(id object, id keyOrKeys, BOOL isASet,DSKVODidChangeDetailSetupFunc didChangeDetailSetupFunc, DSKVODidChangeNotificationPopFunc didChangeNotificationPopFunc, void *popInfo) {
    遍历所有的observer {
        [observer observeValueForKeyPath:keyPath ofObject:object change:changeDictionary context:context];
    }
}

你可能感兴趣的:(KVO底层伪代码)