假如現(xiàn)在有一個(gè)業(yè)務(wù)需求,在項(xiàng)目中每個(gè)控制器界面將要顯示的時(shí)候執(zhí)行一段代碼,可能你第一時(shí)間想到的就是新建一個(gè)基類控制器BaseViewController,然后在BaseViewController中重寫viewWillAppear方法,后面的控制器都繼承自這個(gè)BaseViewController,這樣不是不行,只是后面新建的每一個(gè)控制器都對(duì)父類進(jìn)行了修改,這樣是很消耗內(nèi)存和資源的一個(gè)操作,現(xiàn)在用runtime,交換UIViewController中的viewWillAppear方法的實(shí)現(xiàn):
先附上BaseViewController中的代碼:
+(void)load
{
NSString*className=NSStringFromClass(self.class);
NSLog(@"classname%@",className);
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
Class class =[self 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);
}
});
}
-(void)xxx_viewWillAppear:(BOOL)animated
{
NSLog(@"viewWillAppear:%@",self);
[self xxx_viewWillAppear:animated];
self.navigationController.navigationBar.hidden = YES;
}
這段代碼的作用是替換UIViewController的viewWillAppear方法,所以以后每個(gè)頁面出現(xiàn)的時(shí)候就會(huì)執(zhí)行代碼中-(void)xxx_viewWillAppear:(BOOL)animated這個(gè)方法,因?yàn)樘鎿Q系統(tǒng)方法的業(yè)務(wù)需求只需要執(zhí)行一次,所以代碼中用到的GCD的dispatch_once函數(shù)