iOS开发KVO底层原理四步曲

2018-12-25  本文已影响0人  2thousand17

kvo底层是用runtime实现的,核心原理一共有四步。

1. 根据已有类获取kvo子类类名:

NSString *kvoClassName = [NSString stringWithFormat:@"CBKVO_%@",NSStringFromClass([self class])];
Method setMethod = class_getInstanceMethod([self class], NSSelectorFromString(setName(keyPath)));
NSString *setName(NSString *keyPath) {
    NSString *setName = [NSString stringWithFormat:@"set%@%@:",[[keyPath substringToIndex:1] uppercaseString],[keyPath substringFromIndex:1]];
    return setName;
}

2. 根据类名,创建子类,添加自定义的set方法:

///2.1创建类
Class kvoClass = objc_allocateClassPair([self class], kvoClassName.UTF8String, 0);
//2.2添加方法
class_addMethod(kvoClass, NSSelectorFromString(setName(keyPath)), (IMP)KVO_SetMethod, method_getTypeEncoding(setMethod));
//2.3注册新类
objc_registerClassPair(kvoClass);

3. 交换两个类的指针:

object_setClass(self, kvoClass);

4. 在自定义的set函数中调用父类的set方法,改变属性值:

void KVO_SetMethod(id self ,SEL _cmd ,id value) {
    NSLog(@"set方法执行了%@--%@",self,NSStringFromSelector(_cmd));
    struct objc_super superClass = {
        .receiver = self,
        .super_class = class_getSuperclass([self class]),
    };
    void (*cbkvo_super)(void *,SEL,id) = (void *)objc_msgSendSuper;
    cbkvo_super(&superClass,_cmd,value);
}

结语:上述四步展示的就是KVO底层实现所调用的runtime API,下篇博客将会介绍自定义KVO详细的demo实现。

上一篇下一篇

猜你喜欢

热点阅读