UIViewController方法调整不起作用

时间:2017-01-04 21:14:18

标签: ios objective-c method-swizzling

我在UIViewController上使用一个类别来调用多个ViewControllers中的viewWillAppear:方法。

@implementation UIViewController (Tracking)

+(void)load
{
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        Class class = [self class];

        SEL originalSelector = @selector(viewWillAppear:);
        SEL swizzledSelector = @selector(xx_viewWillAppear:);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(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);
        }

    });
}

-(void)xx_viewWillAppear:(BOOL)animated
{
    [self xx_viewWillAppear:animated];

    NSLog(@"VC loaded");
}

@end

当我从Storyboard加载初始VC时,从不调用混合方法。仅当VC中的viewWillAppear方法被注释掉时才会调用它。但是,当我删除类别并将代码移动到单个VC中时,两个方法都被调用。

#import "ViewController.h"
#import "UIViewController+Tracking.h"

@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

-(void)viewWillAppear:(BOOL)animated
{
    NSLog(@"Inside Controller1");
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

如果它将被调整,可以在VC中实现viewWillAppear吗?如果没有,如果我需要在VC的viewWillAppear中编写一些代码,我该如何处理呢?

1 个答案:

答案 0 :(得分:2)

您需要从super调用viewWillAppear:中的ViewController,否则基类(UIViewController)中的方法将无法执行,那就是那个你一动不动。

以下版本的viewWillAppear:应该会为您提供预期的结果:

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    NSLog(@"Inside Controller1");
}