runtime 實現方法交換 viewwillappear方法

面試題:在程序中方法實現只執行一次,利用runtime方法交換重寫viewwillappear。

1、新建分類 

#import "UIViewController+swizzling.h"
#import <objc/runtime.h>

@implementation UIViewController (swizzling)

//load方法會在類第一次加載的時候被調用
//調用的時間比較靠前,適合在這個方法裏做方法交換
+ (void)load{
    //方法交換應該被保證,在程序中只會執行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"once load");
        //獲得viewController的生命週期方法的selector
        SEL systemSel = @selector(viewWillAppear:);
        //自己實現的將要被交換的方法的selector
        SEL swizzSel = @selector(swiz_viewWillAppear:);
        //兩個方法的Method
        Method systemMethod = class_getInstanceMethod([self class], systemSel);
        Method swizzMethod = class_getInstanceMethod([self class], swizzSel);

        //首先動態添加方法,實現是被交換的方法,返回值表示添加成功還是失敗
        BOOL isAdd = class_addMethod(self, systemSel, method_getImplementation(swizzMethod), method_getTypeEncoding(swizzMethod));
        if (isAdd) {
            //如果成功,說明類中不存在這個方法的實現
            //將被交換方法的實現替換到這個並不存在的實現
            class_replaceMethod(self, swizzSel, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
        }else{
            //否則,交換兩個方法的實現
            method_exchangeImplementations(systemMethod, swizzMethod);
        }

    });
}

- (void)swiz_viewWillAppear:(BOOL)animated{
    //這時候調用自己,看起來像是死循環
    //但是其實自己的實現已經被替換了
    [self swiz_viewWillAppear:animated];
    NSLog(@"swap");
}

2、測試,首先輸出swizzle  然後輸出viewWillAppear

在一個自己定義的viewController中重寫viewWillAppear

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章