0

我需要覆盖在此方法中- (void)viewWillAppear:(BOOL)animated添加的所有 ViewController 。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首先调用,然后viewWillAppearIRViewController2. 在此之后,我的应用程序因 EXC_BAD_ACCESS 而崩溃。怎么了?

4

1 回答 1

2

如果你不能使用子类,因为你想在全局范围内使用它,但又不想丢失旧版本的方法(所以类别覆盖是不可能的),那么你需要摆脱旧方法,放入你的新方法,然后调用旧方法......我过去曾使用过名为JRSwizzle的东西来执行此操作,它无需编写一堆运行时代码就可以轻松进行调配。

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或您正在使用的任何方法。

于 2013-05-09T14:41:52.573 回答