【发布时间】:2019-10-09 15:42:01
【问题描述】:
班级Person:
@implementation Person
- (void)sayHi {
NSLog(@"hi");
}
- (void)sayHello {
NSLog(@"hello");
}
- (void)swizzlingMethod {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL HI_SEL = @selector(sayHi);
SEL HELLO_SEL = @selector(sayHello);
Method HI_METHOD = class_getInstanceMethod(self.class, HI_SEL);
Method HELLO_METHOD = class_getInstanceMethod(self.class, HELLO_SEL);
BOOL addSuccess = class_addMethod(self.class, HI_SEL, method_getImplementation(HELLO_METHOD), method_getTypeEncoding(HELLO_METHOD));
if (addSuccess) {
class_replaceMethod(self.class, HI_SEL, method_getImplementation(HELLO_METHOD), method_getTypeEncoding(HELLO_METHOD));
} else {
method_exchangeImplementations(HI_METHOD, HELLO_METHOD);
}
});
}
@end
当 Person 的实例调用 swizzlingMethod 时,方法 sayHi 和方法 sayHello 将被交换。
然而,一旦实例调用swizzlingMethod,所有实例的方法都将被交换:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
Person *person1 = [Person new];
[person1 swizzlingMethod];
[person1 sayHi];
Person *person2 = [Person new];
[person2 sayHi];
}
即使 person2 没有调用 swizzlingMethod,控制台也会打印 hello 和 hello。
我想要的只是交换了person1的方法。那么有什么方法可以帮助实现它吗?
【问题讨论】:
标签: objective-c runtime