iOS - Runtime Swizzling 源码剖析

简介: Runtime源码下载源码位于objc-class-old.m
void method_exchangeImplementations(Method m1_gen, Method m2_gen)
{
    IMP m1_imp;
    old_method *m1 = oldmethod(m1_gen);
    old_method *m2 = oldmethod(m2_gen);
    if (!m1  ||  !m2) return;
    impLock.lock();
    m1_imp = m1->method_imp;
    m1->method_imp = m2->method_imp;
    m2->method_imp = m1_imp;
    impLock.unlock();
}


objc-runtime-new.m

void method_exchangeImplementations(Method m1, Method m2)
{
    if (!m1  ||  !m2) return;
    mutex_locker_t lock(runtimeLock);
    IMP imp1 = m1->imp(false);
    IMP imp2 = m2->imp(false);
    SEL sel1 = m1->name();
    SEL sel2 = m2->name();
    m1->setImp(imp2);
    m2->setImp(imp1);
    // RR/AWZ updates are slow because class is unknown
    // Cache updates are slow because class is unknown
    // fixme build list of classes whose Methods are known externally?
    flushCaches(nil, __func__, [sel1, sel2, imp1, imp2](Class c){
        return c->cache.shouldFlush(sel1, imp1) || c->cache.shouldFlush(sel2, imp2);
    });
    adjustCustomFlagsForMethodChange(nil, m1);
    adjustCustomFlagsForMethodChange(nil, m2);
}

IMP imp(bool needsLock) const {
        if (isSmall()) {
            IMP imp = remappedImp(needsLock);
            if (!imp)
                imp = ptrauth_sign_unauthenticated(small().imp.get(),
                                                   ptrauth_key_function_pointer, 0);
            return imp;
        }
        return big().imp;
    }

void setImp(IMP imp) {
        if (isSmall()) {
            remapImp(imp);
        } else {
            big().imp = imp;
        }
    }


从源码来看,底层直接交换了SEL的 IMP


相关文章
|
7月前
|
API iOS开发
iOS面试关于runtime
iOS面试关于runtime
58 0
|
编译器 iOS开发
iOS Runtime详细介绍及实战使用(二)
iOS Runtime详细介绍及实战使用
 iOS Runtime详细介绍及实战使用(二)
|
API iOS开发
iOS Runtime详细介绍及实战使用(一)
iOS Runtime详细介绍及实战使用
|
iOS开发
iOS开发- runtime基本用法解析和用runtime给键盘添加工具栏和按钮响应事件
iOS开发- runtime基本用法解析和用runtime给键盘添加工具栏和按钮响应事件
118 0
|
JSON 前端开发 JavaScript
iOS Principle:Runtime(下)
iOS Principle:Runtime(下)
74 0
iOS Principle:Runtime(下)
|
缓存 编译器 Swift
iOS Principle:Runtime(中)
iOS Principle:Runtime(中)
147 0
iOS Principle:Runtime(中)
|
存储 缓存 编译器
iOS Principle:Runtime(上)
iOS Principle:Runtime(上)
95 0
iOS Principle:Runtime(上)
|
iOS开发
iOS - Runtime 动态添加属性
我们在开发中常常使用类目Category为一些已有的类扩展功能。虽然继承也能够为已有类增加新的方法,而且相比类目更是具有增加属性的优势,但是继承毕竟是一个重量级的操作,添加不必要的继承关系无疑增加了代码的复杂度。