交换实例方法:其中Class参数一定得是实例对象的类(实例对象的isa指向它的Class(储存所有减号方法)object_getClass(obj))
static void _exchanged_instance_method(SEL originalSelector, SEL swizzledSelector, Class class){
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
}
else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
交换静态方法(类): 其中class 参数一定要元类(metaClass),Class对象的isa指向元类(储存所有加号方法)object_getClass(object_getClass(obj))
static void _exchanged_class_method(SEL originalSelector, SEL swizzledSelector, Class class){
Method originalMethod = class_getClassMethod(class, originalSelector);
Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
}
else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
注意: 静态方法中的self 是类对象,实例方法中的self 是实例对象,可以用一下方法测试一下:
- (void)viewDidLoad {
[super viewDidLoad];
[self instanceMethod];
[ViewController classMethod];
}
- (void)instanceMethod {
NSLog(@"%p",self);
NSLog(@"%p",object_getClass((id)self));
}
+ (void)classMethod1 {
NSLog(@"%p",self);
//[self instanceMethod] 会报错找不到instanceMethod 方法
//[self classMethod2] 编译器不会报错而且能正常调用
}
+ (void)classMethod2{
NSLog(@"%p",self);
}
最后附一幅经典的图:
网友评论