对于在此方法中添加- (void)viewWillAppear:(BOOL)animated
的所有ViewControllers,我需要覆盖NSLog(@"blabla")
。即每次调用viewWillAppear后都会调用实现的viewWillAppear +我的NSLog消息的早期实现。可能吗?如果是,请给我一个建议。
目前我已尝试过此代码
@implementation RuntimeTest
IMP previusImp;
IMP newIMP;
- (void)ovverrideViewWillAppearInViewController:(Class)vcClass {
newIMP = class_getMethodImplementation([self class], @selector(viewWillAppear:));
Method viewWillAppearMethod = class_getInstanceMethod(vcClass, @selector(viewWillAppear:));
previusImp = method_setImplementation(viewWillAppearMethod, newIMP);
}
- (void)viewWillAppear:(BOOL)animated {
previusImp(self, @selector(viewWillAppear:), animated);
NSLog(@"log2");
}
@end
然后我
@implementation IRViewController2
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"log");
}
@end
我的自定义viewWillAppear
首先调用,然后viewWillAppear
调用IRViewController2
。在此之后我的应用程序崩溃了EXC_BAD_ACCESS。怎么了?
答案 0 :(得分:2)
如果你不能使用子类,因为你想全局地做,但也不想丢失方法的旧版本(所以类别覆盖是不可能的)那么你需要{{3旧方法,放入你的新方法,然后调用旧方法...我过去使用了一个名为swizzle away的东西来执行此操作,它可以轻松调整而无需编写一堆运行时代码
if (![self jr_swizzleMethod:@selector(originalInit) withMethod:@selector(init) error:&err])
{
NSLog(@"unable to jr_swizzle methods, error: %@",err);
exit(EXIT_FAILURE);
}
if (![self jr_swizzleMethod:@selector(init) withMethod:@selector(myInit) error:&err])
{
NSLog(@"unable to jr_swizzle methods, error: %@",err);
exit(EXIT_FAILURE);
}
然后您的-myInit
方法可以调用-originalInit
或您正在使用的任何方法。