本人項目已經(jīng)更新了快2年了,突然要求更改app里面的字體蛹稍,如果按照傳統(tǒng)的方式一個一個label吧黄,button,textfield等等通過font來改變那么我就要吐血了唆姐,想到了用runTime來改變初始化方法拗慨。我覺得這個是最方便的方式來。
先上代碼奉芦,然后和大家說說我入過的坑赵抢。
+ (void)load {
[super load];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//改變init方法
SEL origialSEL1 = @selector(init);
SEL swizzledSEL1 = @selector(LY_init);
[self swizzledMethodWithOriginalSEL:origialSEL1 withSwizzledSEL:swizzledSEL1];
//改變initWithFrame方法
SEL origialSEL2 = @selector(initWithFrame:);
SEL swizzledSEL2 = @selector(LY_initWithFrame:);
[self swizzledMethodWithOriginalSEL:origialSEL2 withSwizzledSEL:swizzledSEL2];
//改變awakeFromNib方法
SEL origialSEL3 = @selector(awakeFromNib);
SEL swizzledSEL3 = @selector(LY_awakeFromNib);
[self swizzledMethodWithOriginalSEL:origialSEL3 withSwizzledSEL:swizzledSEL3];
});
}
+ (void)swizzledMethodWithOriginalSEL:(SEL)originalSEL withSwizzledSEL:(SEL)swizzledSEL {
Class class = [self class];
Method originalMethod = class_getInstanceMethod(class, originalSEL);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSEL);
BOOL didAddMethod = class_addMethod(class, originalSEL, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class, swizzledSEL, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
- (instancetype)LY_init
{
id __self = [self LY_init];
if (__self) {
}
return __self;
}
- (instancetype)LY_initWithFrame:(CGRect)frame
{
id __self = [self LY_initWithFrame:frame];
if (self) {
}
return __self;
}
- (void)LY_awakeFromNib {
[self LY_awakeFromNib];
}
先給大家講解一下代碼,+ (void)load{}這個方法是在加載label之前就運行這個方法的声功,這個方法是在main函數(shù)之前走的烦却,為了保證方法交換只走一次,所以用了一個dispatch_once先巴,而在下面的三個方法里面其爵,大家可以看到在初始化的時候,比如在LY_init方法里面是這么初始化的:id __self = [self LY_init];有的童鞋會說這不是在本類里面調(diào)用自己伸蚯,那不是死循環(huán)了么摩渺,大家要記住這個地方方法名稱已經(jīng)交換了,所以[self LY_init]這個地方實際上指向的是系統(tǒng)的init方法剂邮。這個地方一定要注意证逻。。抗斤。
以下是我進(jìn)的坑囚企,很多。瑞眼。龙宏。。
首先在class這個地方伤疙,我剛開始用的是Class class = object_getClass((id)self); 然后發(fā)現(xiàn)拿到的method為空银酗,后來看資料才發(fā)現(xiàn)如果是類方法是用這個拿class 實例方法要用 Class class = [self class];在一個就是Method originalMethod = class_getInstanceMethod(class, originalSEL);在拿到method的時候我用的也是類方法class_getClassMethod辆影。
大家做的時候一定要注意是類方法還是實例方法。黍特。蛙讥。