Method Swizzing

111 阅读1分钟

参考这篇文章 juejin.cn/post/692423…

如果origin method 为空, 为 origin method 添加 swizzing method 的 iMP

如果 不为空,但是origin method 是从 super class 继承过来的,

为 本类 add_instance([self class] @selector(origin method), imp_get(swizzing mehod), imp_type_encode(swizzing method))

否者直接交换

参照代码:

` Method originMethod = class_getInstanceMethod([self class], @selector(originMethod)); Method swizzlingMethod = class_getInstanceMethod([self class], @selector(BMethod));

    if (!originMethod) {
        class_addMethod([self class], @selector(originMethod), method_getImplementation(swizzlingMethod), method_getTypeEncoding(swizzlingMethod));
        method_setImplementation(swizzlingMethod, imp_implementationWithBlock(^{}));
        return self;;
    }
    
    bool isAdd = class_addMethod([self class], @selector(originMethod), method_getImplementation(swizzlingMethod), method_getTypeEncoding(swizzlingMethod));
    if (isAdd) {
        class_replaceMethod([self class], @selector(BMethod), method_getImplementation(originMethod), method_getTypeEncoding(originMethod));
    } else {
        method_exchangeImplementations(originMethod, swizzlingMethod);
    }`
   

这里面有2个关键runtime函数:

addMethod(Class cls, SEL name, IMP imp, const char *types, bool replace) if ((m = getMethodNoSuper_nolock(cls, name)))

只添加本类的方法

但是刚开始查找方法时,本类没实现会查找super class:

getMethod_nolock(Class cls, SEL sel) while (cls && ((m = getMethodNoSuper_nolock(cls, sel))) == nil) { cls = cls->getSuperclass(); }