runtime运行时应用场景-method swizzling

实际开发中可能面临这样的需求:

  • 需要把所有的UILabel的字体放大2号
  • 需要给所有ViewController添加友盟统计

简单粗暴地方法就是UILabel和ViewController挨个改,但是作为一个程序员,这样改就太丢人了。就算不考虑自己的面子,也总得为公司的发展大计着想吧。

如果是项目开始,可以考虑建个BaseViewController,或者用Category也能实现。可是如果是项目已经有了一定规模之后,再提出以上需求,就需要用到更深层次的技术(runtime)了。

先是UILabel字体大小的问题,新建一个UILabel的category

#import <UIKit/UIKit.h>  
@interface UILabel (WFFontLabel)  
@end 

具体实现

    #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  

当然,如果想更严谨一些,可以写成下面这样(个人认为没有必要)

static dispatch_once_t onceToken;  
   dispatch_once(&onceToken, ^{  
       Class class = [self class];  
  
       Method originalMethod2 = class_getInstanceMethod(class, @selector(setFont:));  
       Method swizzledMethod2 = class_getInstanceMethod(class, @selector(WFSetFont:));  
  
       BOOL didAddMethod2 = class_addMethod(class, @selector(setFont:), method_getImplementation(swizzledMethod2), method_getTypeEncoding(swizzledMethod2));  
  
       if (didAddMethod2) {  
           class_replaceMethod(class,  
                               @selector(WFSetFont:),  
                               method_getImplementation(originalMethod2),  
                               method_getTypeEncoding(originalMethod2));  
       }else {  
           method_exchangeImplementations(originalMethod2, swizzledMethod2);  
       }  
  
   });

另外一个给所有ViewController添加友盟统计,类似的,新建一个viewcontroller的category

    #import <UIKit/UIKit.h>  
    @interface UIViewController (WFAnalysis)  
    @end  

具体实现

    #import "UIViewController+WFAnalysis.h"  
    #import <objc/message.h>  
    
    @implementation UIViewController (WFAnalysis)  
      
    + (void)load {  
        [super load];  
        Method orgMethod = class_getInstanceMethod([self class], @selector(viewWillAppear:));  
        Method swizzledMethod = class_getInstanceMethod([self class], @selector(customViewWillAppear:));  
      
        method_exchangeImplementations(orgMethod, swizzledMethod);  
    }  
      
    - (void)customViewWillAppear:(BOOL)animated {  
        [self customViewWillAppear:animated];  
        NSLog(@"可以在这里添加统计代码");  
    }  
      
    @end  

原文地址:http://blog.csdn.net/zwf_apple/article/details/53127706

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,204评论 4 61
  • 何为闺蜜,要好,亲密,无话不谈。人的一生中总有那么一个或几个好闺蜜/好基友。哪怕她历经铅华、子孙满堂,都不会妨碍...
    有个二货居然阅读 1,885评论 0 1
  • 【导读】不做好准备,就是准备失败。顶级销售冠军拜访客户前都会做哪些准备呢?看看你和他们的差距在哪里。怡历得为你揭秘...
    蜗牛恋峰阅读 3,959评论 0 0
  • 2015年3月17日,我入职实习了,虽然不是学生时代的第一次实习,但我知道这是学生时代的最后一次实习。公司里...
    CoolEgos阅读 1,404评论 0 1
  • 题目描述: 对于每一个正整数奇数n,输出一个n X n矩阵(奇数阶魔阵), 矩阵元素由1~n平方整数组成, 矩阵的...
    板混DK阅读 4,903评论 0 2