iOS Swizzle 方法出现问题.

我通过以下方式hook方法,

static IMP _original_viewWillAppear;
void _swizzle_viewWillAppear(id self, SEL _cmd, BOOL animated) {
    NSDate *start = [NSDate date];
    
    void (*ori_imp)(id, SEL, BOOL) = (void(*)(id, SEL, BOOL))_original_viewWillAppear;
    ori_imp(self, _cmd, animated);
    
    NSDate *end = [NSDate date];
    NSTimeInterval elapsed = [end timeIntervalSinceDate:start];
    
    NSLog(@"Elapsed:%f(s)",elapsed);
}

@implementation UIViewControllerTrace

+ (void)startTrace {
    Method ori = class_getInstanceMethod([UIViewController class], @selector(viewDidLoad));
    _original_viewDidLoad = method_setImplementation(ori, (IMP)_swizzle_ViewDidLoad);
    
    ori = class_getInstanceMethod([UIViewController class], @selector(viewWillAppear:));
    _original_viewWillAppear = method_setImplementation(ori, (IMP)_swizzle_viewWillAppear);
}

ViewController的方法:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    sleep(2);
}

我在viewWillAppear sleep多少, hook方法的log都是错误的.

请问为什么会这样?

阅读 3.8k
2 个回答

最好找到了一个解决方法, 参照了PonyDebugger的网络监控实现方法, 使用rumtime去hook所有类(当然需要去掉一些系统自带的UIViewController). 然后就可以统计到VC的各种方法的运行时间.

     [super viewWillAppear:animated];

此时执行父类的方法,会被替换到你的_swizzle_viewWillAppear方法里 传进来的self是你的子类
此时不会再次调用子类的viewWillAppear方法

    NSDate *start = [NSDate date];
    NSLog(@"%@start%@",self,start);

    
    void (*ori_imp)(id, SEL, BOOL) = (void(*)(id, SEL, BOOL))_original_viewWillAppear;
    ori_imp(self, _cmd, animated);
    
  //可以试着替换下方法 就可以了例如切换到viewDidAppear中 sleep
  //   IMP imp = class_getMethodImplementation([self class], @selector(viewDidAppear:));
  //   void (*ori_imp)(id, SEL, BOOL) = (void(*)(id, SEL, BOOL))imp;
  //   ori_imp(self, _cmd, animated);
    
    
    NSDate *end = [NSDate date];
    NSLog(@"%@end%@",self,end);
    NSTimeInterval elapsed = [end timeIntervalSinceDate:start];
    NSLog(@"Elapsed:%f(s)",elapsed);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题