Swizzling

首先声明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)