我正在遵循此article,以更好地了解方法混乱的工作方式。我有这样的主视图控制器(这是一个新项目):
#import "GLViewController.h"
#import <objc/runtime.h>
@implementation UIViewController (Tracking)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [UIViewController class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(xxx_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);
}
});
}
#pragma mark - Method Swizzling
- (void)xxx_viewWillAppear:(BOOL)animated {
[self xxx_viewWillAppear:animated];
NSLog(@"viewWillAppear: %@", self);
}
@end
@implementation GLViewController
-(void)viewWillAppear:(BOOL)animated
{
NSLog(@"glviewappear");
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
如果运行此命令,则将打印glviewappear,如果删除
-(void)viewWillAppear:(BOOL)animated
{
NSLog(@"glviewappear");
}
然后打印
viewWillAppear: <GLViewController: 0x9d11a90>
。我的项目需要能够同时使用这两种方法。有没有办法做到这一点? 最佳答案
有一个简单的原因。您没有调用UIViewController实现,因为您没有调用[super viewWillAppear:animated]
。
做就是了:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"glviewappear");
}
这是更详细的说明
Objective C类中的每个方法都不过是一个简单的函数,通过分配表中保存的指针进行引用:键是选择器,它们的关联值是每个方法实现的指针(
IMP
)。麻烦时,只需交换调度表中的两个指针,即可交换引用的函数。由于分派表已附加到该类,因此仅在执行它的类中发生混乱,而在子类中则不会发生混乱。
在您的情况下,有3种不同的功能在起作用:
UIViewController在分配表中具有指向以下功能的指针。这些功能在运行时会通过交换交换。
viewWillAppear:
(现在指向xxx_viewWillAppear:
实现)xxx_viewWillAppear:
(现在指向viewWillAppear:
实现)GLViewController还有另一个指针,指向其自己的
viewWillAppear:
实现。如果不调用
super
,则不会访问UIViewController
类的调度表,因此根本就不会调用实现。当您删除viewWillAppear:方法时,显然可以使用,因为将自动调用超级实现。
关于ios - 方法旋转不正确触发?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23748573/