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