前言
自己对 Method Swizzling 的误解,希望能帮到有同样误解的朋友。
正文
在 Nshipster 有一篇关于 Method Swizzling 的介绍,里面用到的代码是这样的:
#import "UIViewController+Tracking.h"
#import <objc/runtime.h>
@implementation UIViewController (Tracking)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(xxx_viewWillAppear:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
// When swizzling a class method, use the following:
// Class class = object_getClass((id)self);
// ...
// 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);
}
});
}
#pragma mark - Method Swizzling
- (void)xxx_viewWillAppear:(BOOL)animated {
[self xxx_viewWillAppear:animated];
NSLog(@"viewWillAppear: %@", self);
}
@end
自己的 viewController 代码:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
NSLog(@"originalViewWillAppear: %@", self);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
问:输出什么?
答案是:
originalViewWillAppear: <ViewController: 0x7fb047805830>
为什么在这里 xxx_viewWillAppear:
里的 log 不打印呢?
因为这里 Method Swizzling 所替换的是 UIViewController 类的 viewWillAppear:
方法,而在子类 ViewController 并没有调用到父类的方法,而是重写了这个方法,使得 APP 运行中的代码只有子类的 viewWillAppear:
。如果需要父类的方法也调用到,需要在 viewWillAppear:
中加上 [super viewWillAppear:animated];
。
因此,在编码过程中,需要注意代码规范,生命周期相关的基本 super 调用不能漏写,以防出现难以排查的 BUG。(是的,我就是出现了这种 BUG_(:з」∠)_)。
嗨呀,贼气。
网友评论