最近在看 《iOS应用逆向与开发》。在4.3.4 runtime的使用中看到了方法交换的写法,不理解 method_exchangeImplementations 就可以完成的事 为什么要加个判断 class_addMethod 是否yes,yes为何class_replaceMethod ,no为何是method_exchangeImplementations,特此搜索了一下 原文链接
我们有没有想过这种情况: " 周全起见,有两种情况要考虑一下。第一种情况是要复写的方法(overridden)并没有在目标类中实现(notimplemented),而是在其父类中实现了。第二种情况是这个方法已经存在于目标类中(does existin the class itself)。这两种情况要区别对待。 (译注: 这个地方有点要明确一下,它的目的是为了使用一个重写的方法替换掉原来的方法。但重写的方法可能是在父类中重写的,也可能是在子类中重写的。) 对于第一种情况,应当先在目标类增加一个新的实现方法(override),然后将复写的方法替换为原先(的实现(original one)。 对于第二情况(在目标类重写的方法)。这时可以通过method_exchangeImplementations来完成交换."
下面是monkeydev作者的源码
#import <objc/runtime.h>
#import "UIViewController+Swizzle.h"
@implementation UIViewController(Swizzle)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(ms_viewWillAppear:);
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);
}
});
}
#pragma mark - Method Swizzling
- (void)ms_viewWillAppear:(BOOL)animated {
[self ms_viewWillAppear:animated];
NSLog(@"viewWillAppear: %@", self);
}
@end
网友评论