runtime簡單的使用解決實際問題(交換方法)

友盟統計中要求在每一個頁面的viewWillAppear和viewWillDisappear方法中添加友盟統計的方法:app

若是是項目開始,能夠考慮建個BaseViewController,或者用Category也能實現。但是若是是項目已經有了必定規模以後,再提出以上需求,就須要用到更深層次的技術(runtime)了。字體

新建一個viewcontroller的categoryspa

具體代碼:指針

#import "UIViewController+UmengAnalysis.h"
#import <objc/message.h>
#import "UMMobClick/MobClick.h"

@implementation UIViewController (UmengAnalysis)
+ (void)load {
    [super load];
// 獲取兩個方法的IMP(指針)
    Method orgMethod = class_getInstanceMethod([self class], @selector(viewWillAppear:));
    Method swizzledMethod = class_getInstanceMethod([self class], @selector(customViewWillAppear:));
//交換指針
    method_exchangeImplementations(orgMethod, swizzledMethod);
    
    Method orgDisMethod = class_getInstanceMethod([self class], @selector(viewWillDisappear:));
    Method swizzledDisMethod = class_getInstanceMethod([self class], @selector(customViewWillDisAppear:));
    method_exchangeImplementations(orgDisMethod, swizzledDisMethod);
}

- (void)customViewWillAppear:(BOOL)animated {
    [self customViewWillAppear:animated];
    [MobClick beginLogPageView:NSStringFromClass([self class])];
}
- (void)customViewWillDisAppear:(BOOL)animated{
    [self customViewWillDisAppear:animated];
    [MobClick endLogPageView:NSStringFromClass([self class])];
}
@end

UILabel字體大小的問題,相似的新建一個UILabel的categorycode

#import "UILabel+WFFontLabel.h"  
    #import <objc/runtime.h>  

    @implementation UILabel (WFFontLabel)  

    + (void)load {  
        static dispatch_once_t onceToken;  
        dispatch_once(&onceToken, ^{  
            Class class = [self class];  

            // 獲取兩個方法的IMP(指針)  
            Method originalMethod2 = class_getInstanceMethod(class, @selector(setFont:));  
            Method swizzledMethod2 = class_getInstanceMethod(class, @selector(WFSetFont:));  

            // 交換IMP  
            method_exchangeImplementations(originalMethod2, swizzledMethod2);  

        });  
    }  

    - (void)WFSetFont:(UIFont *)font {  
        UIFont * newFont = [UIFont systemFontOfSize:font.pointSize+10];  
        [self WFSetFont:newFont];  
    }  

    @end

 

load類方法會在每一個頁面中被調用,在運行時,viewWillAppearget

方法會被statisticsViewWillAppear替換,viewWillDisappear會被statisticsViewWillDisappear替換,且每一個頁面的viewWillAppear、viewWillDisappear方法仍然有效。io

我的感受這是一個很好地能解決多個頁面統計的分類。class

相關文章
相關標籤/搜索