UIViewController 方法调配不起作用
UIViewController method swizzling not working
我在 UIViewController 上使用一个类别来调配 viewWillAppear: 跨多个 ViewController 的方法。
@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 时,从未调用 swizzled 方法。只有在 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,如果它要被 swizzled?如果不是,如果我需要在 VC 的 viewWillAppear 中编写一些代码,我该如何处理?
您需要从 ViewController
中调用 viewWillAppear:
中的 super
,否则基础 class (UIViewController
) 中的方法将不会执行, 那就是你调配的那个。
viewWillAppear:
的以下版本应该会给您预期的结果:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"Inside Controller1");
}
我在 UIViewController 上使用一个类别来调配 viewWillAppear: 跨多个 ViewController 的方法。
@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 时,从未调用 swizzled 方法。只有在 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,如果它要被 swizzled?如果不是,如果我需要在 VC 的 viewWillAppear 中编写一些代码,我该如何处理?
您需要从 ViewController
中调用 viewWillAppear:
中的 super
,否则基础 class (UIViewController
) 中的方法将不会执行, 那就是你调配的那个。
viewWillAppear:
的以下版本应该会给您预期的结果:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"Inside Controller1");
}