实际开发中可能面临这样的需求:
- 需要把所有的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