美文网首页
runtime 交换实例方法和对象方法标准写法

runtime 交换实例方法和对象方法标准写法

作者: kelvin943 | 来源:发表于2017-02-07 17:08 被阅读58次

    交换实例方法:其中Class参数一定得是实例对象的类(实例对象的isa指向它的Class(储存所有减号方法)object_getClass(obj))

    static void _exchanged_instance_method(SEL originalSelector, SEL swizzledSelector, Class class){
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));
        
        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        }
        else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    }
    

    交换静态方法(类): 其中class 参数一定要元类(metaClass),Class对象的isa指向元类(储存所有加号方法)object_getClass(object_getClass(obj))

    static void _exchanged_class_method(SEL originalSelector, SEL swizzledSelector, Class class){
        Method originalMethod = class_getClassMethod(class, originalSelector);
        Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));
        
        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        }
        else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    }
    

    注意: 静态方法中的self 是类对象,实例方法中的self 是实例对象,可以用一下方法测试一下:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [self  instanceMethod];
        [ViewController classMethod];
    }
    
    - (void)instanceMethod {
        NSLog(@"%p",self);
        NSLog(@"%p",object_getClass((id)self));
    }
    
    + (void)classMethod1 {
        NSLog(@"%p",self);
       //[self instanceMethod]       会报错找不到instanceMethod 方法
       //[self classMethod2]         编译器不会报错而且能正常调用
    }
    + (void)classMethod2{
        NSLog(@"%p",self);
    
    }
    

    最后附一幅经典的图:

    相关文章

      网友评论

          本文标题:runtime 交换实例方法和对象方法标准写法

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