+(void)load VS +(void)initialize
每个类的这两个方法都会被Objective-C运行时系统自动调用,+load 方法是在一个类最开始调用的,+initialize 是在应用中第一次调用该类或者他的实例的方式之前调用,这两个方法都可以使用,只有实现了才会被执行,
既然是分类,就会全局监听,+load 能够保证在类初始化的时候会被加载,通过这个操作可以做一些统一的操作,但是+initialize 并不能保证什么时候被调用,有可能永远也不会被调用,如果应用程序从未直接给该类发送任何消息,则无法调用
在调用load 方法的时候,我们通常是通过
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
//我们采取了一个预防措施,防止运行时多次被执行,确保代码即使使用在多线程环境下也只会被执行一次,我们优先使用GCD
});
调用_cmd
下面这段代码不会影响执行,也不会进入死循环,
aop_viewWillAppear 这个方法会在运行时进入到协同的viewWillAppear 方法执行,但是我们不能在这个里面调用viewWillAppear,以免造成无法控制的危险
+(void)load{
[super load];
method_exchangeImplementations(class_getInstanceMethod(self, @selector(viewWillAppear:)),
class_getInstanceMethod(self, @selector(load_viewWillAppear:)));
NSLog(@"---%s---",FUNCTION);
}
-(void)load_viewWillAppear:(BOOL)animated{
NSLog(@"---%s---",FUNCTION);
[self load_viewWillAppear:animated];
}
Method Swizzling的实现原理可以理解为”方法互换“。假设我们将A和B两个方法进行互换,向A方法发送消息时执行的却是B方法,向B方法发送消息时执行的是A方法。
例如我们上面的代码,系统调用UIViewController的viewDidLoad方法时,实际上执行的是我们实现的load_viewWillAppear方法。而我们在load_viewWillAppear方法内部调用[self load_viewWillAppear];时,执行的是UIViewController的viewDidLoad方法。
网友评论