Objective-C 如何hook系统私有类?
Tip:在读这篇文章之前,最好对 SEL、IMP 有一定的了解。否则很容易懵的,得不偿失哦~
众所周知,OC中Runtime黑魔法的强大!也叫做Method Swizzling,在很多博客中,给了个例子,比如你要hook UIViewController的viewDidAppear:animated方法。通常就是创建一个UIViewController的Category,然后在+load方法中,做以下处理:
+ (void)load {
[super load];
Method didFromMethod = class_getInstanceMethod([self class], @selector(viewDidAppear:));
Method didToMethod = class_getInstanceMethod([self class], @selector(swizzlingViewDidAppear:));
method_exchangeImplementations(didFromMethod, didToMethod);
}
- (void)swizzlingViewDidAppear:(BOOL)animated {
NSString *str = NSStringFromClass(self.class);
if(![str containsString:@"UI"]){
NSLog(@"统计打点: %@", str);
}
[self swizzlingViewDidAppear:YES];
}
这样做有没有问题呢?我的回答:当然有!稍后做出解释。
好,进入今天的主题,因为UIViewController是public的,我们可以创建Category,可以继承。但私有类怎么办呢?本来我是想以“UITableViewIndex”这个类为例,这个类是UITableView右边的索引。但是为了可以清晰的看到hook之后方法原实现有没有执行,因此我们用自定义的类来实现。此方法没有局限性,强烈推荐。
创建两个测试用的类:
- MyClass
//------- .h -------
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
- (void)eat;
@end
//------- .m -------
#import