美文网首页
runtime的消息交换

runtime的消息交换

作者: Tonyliu_ | 来源:发表于2018-04-20 17:20 被阅读0次

    Method Swizzing

    顾名思义,就是讲2个方法进行交换,由原来的  A---MethodA_A  B---Method_B,变为 A---Method_B  B---Method_A
    

    Method Swizzing有什么用处呢?

    比如说我们想统计每一个ViewController展示给用户的次数,我们可以在每个ViewController里的ViewDidApper里添加跟踪代码,但是这个过于麻烦,需要在每个ViewController里写重复的代码。
    
    • 我们可以创建一个子类,但是需要创建UIViewController、UITableViewController、UINavigationController以及UIKit里的ViewController的子类,同样会很麻烦
    • 在这种情况下我们就可以使用Method Swizzing

    Method Swizzing相关函数介绍

    1、获取一个方法的SEL

    class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name)
    
    • 参数一:方法所在类
    • 参数二:方法名

    2、获取一个方法的IMP

    class_getMethodImplementation(Class _Nullable cls, SEL _Nonnull name) 
    

    3、添加一个方法

    class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types) 
    
    • 参数一:添加方法所在类
    • 参数二:添加方法名
    • 参数三:指向一个方法实现的指针
    • 参数四:参数类型的说明(方法返回值,参数等信息)

    4、用一个方法替换另外一个方法

    class_replaceMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types)
    

    5、交换方法

    method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2)
    

    Method Swizzling 注意要点

    一、在+load()方法中实现

    Objective-C在运行时会自动调用类的两个方法+load和+initialize。+load会在类初始加载时调用, +initialize方法是以懒加载的方式被调用的,如果程序一直没有给某个类或它的子类发送消息,那么这个类的 +initialize方法是永远不会被调用的。所以Swizzling要是写在+initialize方法中,是有可能永远都不被执行。

    二、使用dispatch_once 中执行

        Swizzling会改变全局状态,所以在运行时采取一些预防措施,使用dispatch_once就能够确保代码不管有多少线程都只被执行一次。如果不写进行了偶数次的交换,就相当于没有交换。
    

    参考文章:runtime 黑魔法 Method Swizzing http://zhangzr.cn/2018/02/06/iOS%E5%BC%80%E5%8F%91-runtime-%E9%BB%91%E9%AD%94%E6%B3%95Method-swizzling/

    runtime 如何使用https://halfrost.com/how_to_use_runtime/

    相关文章

      网友评论

          本文标题:runtime的消息交换

          本文链接:https://www.haomeiwen.com/subject/yxjzkftx.html