Runtime梳理(五)Swizzle

这里暂且不说什么是Swizzle,大家可以自行去网上查找。不知道大家在在实际开发的过程中有没有遇到这样的的问题:有一个A类和一个B类,A类中有一个对象方法a,B类中有一个类方法b,AB类之间无继承关系,当调用A类中的a方法时先调用B类中的B方法。

我们先将这两个类创建出来并实现对应的方法

@interface TestA : NSObject
- (void)testA;
@end
@implementation TestA
- (void)testA{
    NSLog(@"%s",__func__);
}
@end

@interface TestB : NSObject
+ (void)testB;
@end
@implementation TestB
+ (void)testB{
    NSLog(@"%s",__func__);
}
@end

创建NSObject的分类

#import "NSObject+Swizzle.h"
#import 
#import "TestB.h"
#import "TestA.h"
@implementation NSObject (Swizzle)
+ (void)load{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        SEL selA = NSSelectorFromString(@"testA");
        Method methodA = class_getInstanceMethod([TestA class], selA);
        
        SEL swizzleA = NSSelectorFromString(@"swizzle_testA");
        Method mSwizzleA = class_getInstanceMethod([self class], swizzleA);
        
        SEL selB = NSSelectorFromString(@"testB");
        Method methodB = class_getClassMethod([TestB class], selB);
        
        IMP impB = class_getMethodImplementation([TestB class], selB);
        IMP impA = class_getMethodImplementation([self class], swizzleA);
        
        
        SEL swizzleB = NSSelectorFromString(@"swizzle_testB");
        Method mSwizzleB = class_getInstanceMethod([self class], swizzleB);
        BOOL resultB = class_addMethod([self class], @selector(swizzle_testB), impB, method_getTypeEncoding(methodB));
        // 交换testB和swizzle_testB方法
        if (resultB) {
            class_replaceMethod([self class], @selector(swizzle_testB), impB, method_getTypeEncoding(methodB));
        }
        else{
            method_exchangeImplementations(mSwizzleB, methodB);
            NSLog(@"bbb");
        }
        
        
        BOOL resultA = class_addMethod([TestA class], selA, impA, method_getTypeEncoding(mSwizzleA));
        // 交换testA和swizzle_testA方法
        if (resultA) {
            NSLog(@"111");
            class_replaceMethod([TestA class], selA, impA, method_getTypeEncoding(mSwizzleA));
        }
        else{
            NSLog(@"222");
            method_exchangeImplementations(methodA, mSwizzleA);
        }
    });
}

- (void)swizzle_testA{
    NSLog(@"%s",__func__);
    [self swizzle_testB];
    [self swizzle_testA];
}

- (void)swizzle_testB{
    NSLog(@"%s",__func__);
    [self swizzle_testB];
}
@end

测试

    TestA  * testa = [TestA new];
    [testa testA];

打印结果

 -[NSObject(Swizzle) swizzle_testA]
 +[TestB testB]
 -[TestA testA]

你可能感兴趣的:(Runtime梳理(五)Swizzle)