美文网首页
iOS-模拟KVO

iOS-模拟KVO

作者: CocoaJason | 来源:发表于2022-03-07 16:59 被阅读0次
@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";
}

相关文章

  • iOS-模拟KVO

  • iOS - KVO

    [toc] 参考 KVO KVC 【 iOS--KVO的实现原理与具体应用 】 【 IOS-详解KVO底层实现 】...

  • iOS-底层原理21-KVO(下)

    iOS-底层原理21-KVO(下) 《iOS底层原理文章汇总》[https://www.jianshu.com/p...

  • 自定义KVO

    导语: 如果对KVO原理不是很熟悉的,可以参考下简书另一篇文章《ios KVO原理探究》,主要是通过模拟KVO底层...

  • iOS-探讨KVO

    KVO是现在面试的时候,算是一个必问的环节,笔者也是在之前做面试准备的时候,查看了一些资料,然后最近又回顾了一下,...

  • iOS-探讨KVO

    KVO是现在面试的时候,算是一个必问的环节,笔者也是在之前做面试准备的时候,查看了一些资料,然后最近又回顾了一下,...

  • 模拟KVO的实现

  • 模拟系统KVO实现

    1.主要方法■添加通知 :cf_ddObserver...■监听通知 :cf_observerValueForKe...

  • iOS-窥探 KVO 本质

    KVO的实现方式 KVO 是我们日常开发经常用到的技术,关于 KVO 的实现相信大家也都有一定的了解,我们来看下苹...

  • iOS- KVC和KVO

    #pragma mark---KVC--- KVC:key(键)-value(值)-code(编码) 键值编码->...

网友评论

      本文标题:iOS-模拟KVO

      本文链接:https://www.haomeiwen.com/subject/pjvyrrtx.html