Swizzling

作者: honzon_0 | 来源:发表于2017-05-17 19:02 被阅读3次

    首先声明4个不同的类,都继承自NSObject,每一个类里面都有一个方法

    @interface Honzon1 : NSObject
    - (void)hozon1Test;
    @end
    @implementation Honzon1
    - (void)hozon1Test {
        NSLog(@"Honzon1");
    }
    @end
    
    @interface Honzon2 : NSObject
    - (void)hozon2Test;
    @end
    @implementation Honzon2
    - (void)hozon2Test {
        NSLog(@"Honzon2");
    }
    @end
    
    @interface Honzon3 : NSObject
    - (void)hozonTest;
    @end
    @implementation Honzon3
    - (void)hozonTest {
        NSLog(@"Honzon3");
    }
    @end
    
    @interface Honzon4 : NSObject
    - (void)hozonTest;
    @end
    @implementation Honzon4
    - (void)hozonTest {
        NSLog(@"Honzon4");
    }
    @end
    

    然后用4个类分别创建4个对象

    Honzon1 *honzon1 = [[Honzon1 alloc] init];
    Honzon2 *honzon2 = [[Honzon2 alloc] init];
    Honzon3 *honzon3 = [[Honzon3 alloc] init];
    Honzon4 *honzon4 = [[Honzon4 alloc] init];
    

    Method Swizzling

    Method honzon1Test = class_getInstanceMethod([honzon1 class], @selector(hozon1Test));
    Method honzon2Test = class_getInstanceMethod([honzon2 class], @selector(hozon2Test));
    
    if (honzon1Test && honzon2Test) {
        method_exchangeImplementations(honzon1Test, honzon2Test);//交换方法实现
    }
    [honzon1 hozon1Test];
    //-> Honzon2
    [honzon2 hozon2Test];
    //-> Honzon1
    

    MethodList Swizzling

    object_setClass(honzon3, [honzon4 class]);//设置方法列表查找类
    object_setClass(honzon4, [Honzon3 class]);
    [honzon3 hozonTest];
    //-> Honzon4
    [honzon4 hozonTest];
    //-> Honzon3
    

    在OC中,事件传递链的最开始是通过objc_msgSend在该类的方法列表(当然也有方法缓存)中通过这个方法名称(SEL),去寻找相对应的方法实现;如果找到了就调用该实现,如果没有就进入消息转发流程。

    通过上述代码的打印,可以看到Method Swizzling(method_exchangeImplementations)是把俩个类的方法实现交换了,所以honzon1通过方法名hozon1Test找到的是Honzon2里面的对象方法hozon2Test的实现,最后打印的是Honzon2,后面的[Honzon2 hozon2Test]也因此打印Honzon1

    MethodList Swizzling,其实是通过修改对象的isa指针指向新的类对象,然后在设置的新类中去按照方法名查找实现,这就导致了一个问题,如果honzon3honzon4中的方法名称不一致的话,就会崩溃。

    而最后为Honzon3设置新类时 ,不能用[honzon3 class];因为honzon3的方法查找类已经设置为Honzon4了。所以 这儿如果使用[honzon4 class]的话,最后打印的还是honzon4

    相关文章

      网友评论

          本文标题:Swizzling

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