你真的懂使用Runtime进行swizzle的最佳写法?

简介: 前言runtime 的黑魔法很多人都一定听过,或者已经在使用了。但是,怎么swizzle方法才是最好呢?一般写法Method originalMethod = class_getInstanceMethod(aClass, originalSel...

前言

runtime 的黑魔法很多人都一定听过,或者已经在使用了。但是,怎么swizzle方法才是最好呢?

一般写法

Method originalMethod = class_getInstanceMethod(aClass, originalSel);
    Method swizzleMethod = class_getInstanceMethod(aClass, swizzleSel);
    method_exchangeImplementations(originalMethod, swizzleMethod);

或者是下面这种方式,swizzle第二种写法:

   Method originalMethod = class_getInstanceMethod(aClass, originalSel);
    Method swizzleMethod = class_getInstanceMethod(aClass, swizzleSel);
    BOOL didAddMethod = class_addMethod(aClass, originalSel, method_getImplementation(swizzleMethod), method_getTypeEncoding(swizzleMethod));
    if (didAddMethod) {
        class_replaceMethod(aClass, swizzleSel, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    }else{
        method_exchangeImplementations(originalMethod, swizzleMethod);
    }

更好写法

其它,这样写,一般不会有问题,但是在一些情况下,比如这个hook的类没有实现你要swizzle的方法,这时是没有swizzle成功的,然后你自己写的 swizzle 里又自己调用自己,就无限循环。

    Method originalInsMethod = class_getInstanceMethod(class, originalSelector);
    // 处理为实例方法
    if (originalInsMethod)
    {
        method_exchangeImplementations(originalInsMethod, swizzledMethod);
    }else{
        // 处理为类方法
        Method originalClassMethod = class_getClassMethod(class, originalSelector);
        if (originalClassMethod)
        {
            method_exchangeImplementations(originalClassMethod, swizzledMethod);
        }else{
            // 如果hook的类没有实现这个方法,则先添加方法,然后设置方法的IMP为一个空block。否则直接class_replaceMethod,则方法实则没有交接
            class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
            method_setImplementation(swizzledMethod, imp_implementationWithBlock(^(id self, SEL _cmd){}));
        }
    }

总结

至于这个为什么会更好? 有时间在慢慢说啦~

参考


注:本文首发于 iHTCboy's blog,如若转载,请注明来源。

目录
相关文章
|
20天前
|
JavaScript 前端开发
js中的bind,call,apply方法的区别以及用法
JavaScript中,`bind`、`call`和`apply`均可改变函数的`this`指向并传递参数。其中,`bind`返回一个新函数,不立即执行;`call`和`apply`则立即执行,且`apply`的参数以数组形式传递。三者在改变`this`指向及传参上功能相似,但在执行时机和参数传递方式上有所区别。
24 1
|
6月前
|
Java
java代码的具体写法示例
java代码的具体写法示例
53 0
|
JavaScript 前端开发
JavaScript call、apply 和 bind 的区别
JavaScript call、apply 和 bind 的区别
|
7月前
|
前端开发 JavaScript
【面试题】 JavaScript 中 call()、apply()、bind() 的用法
【面试题】 JavaScript 中 call()、apply()、bind() 的用法
|
7月前
|
前端开发 JavaScript Java
【面试题】JavaScript 中 call()、apply()、bind() 的用法
【面试题】JavaScript 中 call()、apply()、bind() 的用法
java--Lambda (4)变量的修改
目前知道的可以再Lambda内部修改的只有这两个,作为一个总结,可以直接记住。大家可以直接复制代码进行尝试,记得修改类名同步和引入测试类。
218 0
java--Lambda (4)变量的修改
|
Java API Kotlin
【Kotlin】apply 内联扩展函数 ( apply 函数原型 | apply 函数示例 | Kotlin 调用 Java API )
【Kotlin】apply 内联扩展函数 ( apply 函数原型 | apply 函数示例 | Kotlin 调用 Java API )
233 0
【Kotlin】apply 内联扩展函数 ( apply 函数原型 | apply 函数示例 | Kotlin 调用 Java API )
|
JavaScript 前端开发
JavaScript 中 call()、apply()、bind() 的用法
JavaScript 中 call()、apply()、bind() 的用法
96 0
|
前端开发 JavaScript
一个简单的例子让你轻松地明白JavaScript中apply、call、bind三者的用法及区别
这篇文章也算是讲解了前端面试 常考的知识点 ,即关于JavaScript中apply、call、bind三者的用法及区别。 如果有些小伙伴已经对该知识有一定的了解了,可以直接跳到最后看 总结
132 0