首先声明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
指针指向新的类对象,然后在设置的新类中去按照方法名查找实现,这就导致了一个问题,如果honzon3
和honzon4
中的方法名称不一致的话,就会崩溃。
而最后为Honzon3
设置新类
时 ,不能用[honzon3 class]
;因为honzon3
的方法查找类已经设置为Honzon4
了。所以 这儿如果使用[honzon4 class]
的话,最后打印的还是honzon4
网友评论