iOS-模擬KVO

@interface Person : NSObject

@property (nonatomic, copy) NSString *name;

@end

@interface Person (KVO)

- (void)by_addObserver:(NSObject *)observer
            forKeyPath:(NSString *)keyPath
               options:(NSKeyValueObservingOptions)options
               context:(nullable void *)context;

@end

@implementation Person (KVO)

- (void)by_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context {
    NSString *originClassName = NSStringFromClass(self.class);
    NSString *newClassName = [@"CJ_NSKVONotifying_" stringByAppendingString:originClassName];
    
    Class kvoClass = objc_allocateClassPair([self class], [newClassName UTF8String], 0);
    
    class_addMethod(kvoClass, @selector(setName:), (IMP)setName, "v@:@");
    
    objc_registerClassPair(kvoClass);
    
    object_setClass(self, kvoClass);
    
    objc_setAssociatedObject(self, @"observer", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
}

void setName(id self, SEL _cmd, NSString *name) {
    Class kvoClass = [self class];
    
    object_setClass(self, class_getSuperclass([self class]));
    objc_msgSend(self, @selector(setName:), name);
    
    id objc = objc_getAssociatedObject(self, @"observer");
    
    NSDictionary <NSKeyValueChangeKey, id>*change = @{NSKeyValueChangeKindKey: @1,
                                                      NSKeyValueChangeNewKey:name};
    objc_msgSend(objc, @selector(observeValueForKeyPath:ofObject:change:context:), @"name",self, change,nil);
    object_setClass(self, kvoClass);
    
}

@end
Person *personModel = [[Person alloc] init];
    personModel.name = @"Cocoa";
    
    NSLog(@"%@",object_getClass(personModel));
    [personModel by_addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld context:nil];
    NSLog(@"%@",object_getClass(personModel));
    
    personModel.name = @"Cocoa Jason";
2022-03-03 10:26:52.096757+0800 dsadasdasdsa[10757:17330187] Person
2022-03-03 10:26:52.096907+0800 dsadasdasdsa[10757:17330187] CJ_NSKVONotifying_Person
2022-03-03 10:26:52.097098+0800 dsadasdasdsa[10757:17330187] {
    kind = 1;
    new = "Cocoa Jason";
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容