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];
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容