自定义KVO
Posted coolcold
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义KVO相关的知识,希望对你有一定的参考价值。
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的主要内容,如果未能解决你的问题,请参考以下文章