首页 > 其他 > 详细

自定义KVO

时间:2019-12-21 20:57:52      阅读:99      评论:0      收藏:0      [点我收藏+]

1. 不调用实例变量的方法

2. 动态生成子类 (利用runtime生成:申请类,添加一些方法-set-class等方法,注册类 )

 

#import <Foundation/Foundation.h>

 

NS_ASSUME_NONNULL_BEGIN

 

@interface NSObject (FXKVO)

 

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

 

- (void)fx_observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context;

 

- (void)fx_removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

@end

 

NS_ASSUME_NONNULL_END

 

添加一个NSObject的分类,重写观察者方法

 

- (void)fx_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context{

    //1. 验证set方法

    [self judgeSetterMethodFromKeyPath:keyPath];

    //2. 动态生成子类

//    Class newClass = [self cre];

}

 

#pragma mark - 验证是否存在setter方法,如果不存在抛出异常(例如成员变量添加观察者会崩溃)

- (void)fx_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context{

    //1. 验证set方法

    [self judgeSetterMethodFromKeyPath:keyPath];

    //2. 动态生成子类

    Class newClass = [self creatChildClass];

    //3. 当前对象的类,isa指向newClass

    object_setClass(self, newClass);

}

 

#pragma mark - 动态生成子类

- (Class)creatChildClass{

 // LGKVO_LGPerson

    

    // 2. 动态生成子类

     

    NSString *oldName = NSStringFromClass([self class]);

    NSString *newName = [NSString stringWithFormat:@"%@%@", FXKVOPrefix, oldName];

    Class newClass    = objc_allocateClassPair([self class], newName.UTF8String, 0);

    

    //申请注册到内存中

    objc_registerClassPair(newClass);

    

    // 2.1 子类添加一些方法 class setter

    // class

    SEL classSEL = NSSelectorFromString(@"class");

    Method classM = class_getInstanceMethod([self class], classSEL);

    const char *type = method_getTypeEncoding(classM);

    class_addMethod(newClass, classSEL, (IMP)fx_class, type);

    

    return newClass;

}

自定义KVO

原文:https://www.cnblogs.com/coolcold/p/12078068.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!