runtime运行时应用场景-method swizzling

实际开发中可能面临这样的需求:
  1.  需要把所有的UILabel的字体放大2号
  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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值