这里暂且不说什么是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 <objc/runtime.h>
#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]