美文网首页
runtime理解笔记

runtime理解笔记

作者: 被丢掉的咸鱼 | 来源:发表于2016-05-11 17:37 被阅读20次

.一、交换两个方法的实现,拦截系统自带的方法调用功能

需要用到的方法

获得某个类的类方法

Method class_getClassMethod(Classcls , SEL name)

获得某个类的实例对象方法

Method class_getInstanceMethod(Classcls , SEL name)

交换两个方法的实现

void method_exchangeImplementations(Methodm1 , Method m2)

1. 示例

#import

@interfacebaby :NSObject

+ (void)run;

+ (void)cry;

@end

#import"baby.h"

@implementationbaby

+ (void)run {

NSLog(@"baby会跑");

}

+ (void)cry {

NSLog(@"baby爱哭");

}

@end

调用

[babyrun];

[babycry];

Methodm1 =class_getClassMethod([babyclass],@selector(run));

Methodm2 =class_getClassMethod([babyclass],@selector(cry));

method_exchangeImplementations(m1, m2);

[babyrun];

[babycry];

案例2:拦截系统方法

需求:比如iOS6 升级 iOS7 后需要版本适配,根据不同系统使用不同样式图片(拟物化和扁平化),如何通过不去手动一个个修改每个UIImage的imageNamed:方法就可以实现为该方法中加入版本判断语句?

步骤:

1、为UIImage建一个分类(UIImage+Category)

2、在分类中实现一个自定义方法,方法中写要在系统方法中加入的语句,比如版本判断

+ (UIImage*)xh_imageNamed:(NSString*)name {doubleversion = [[UIDevicecurrentDevice].systemVersiondoubleValue];if(version >=7.0) {// 如果系统版本是7.0以上,使用另外一套文件名结尾是‘_os7’的扁平化图片name = [name stringByAppendingString:@"_os7"];    }return[UIImagexh_imageNamed:name];}

3、分类中重写UIImage的load方法,实现方法的交换(只要能让其执行一次方法交换语句,load再合适不过了)

+ (void)load {// 获取两个类的类方法Method m1 = class_getClassMethod([UIImageclass],@selector(imageNamed:));    Method m2 = class_getClassMethod([UIImageclass],@selector(xh_imageNamed:));// 开始交换方法实现method_exchangeImplementations(m1, m2);}

注意:自定义方法中最后一定要再调用一下系统的方法,让其有加载图片的功能,但是由于方法交换,系统的方法名已经变成了我们自定义的方法名(有点绕,就是用我们的名字能调用系统的方法,用系统的名字能调用我们的方法),这就实现了系统方法的拦截!

利用以上思路,我们还可以给 NSObject 添加分类,统计创建了多少个对象,给控制器添加分类,统计有创建了多少个控制器,特别是公司需求总变的时候,在一些原有控件或模块上添加一个功能,建议使用该方法!

#import

@interfaceUILabel (cataary)

@property(nonatomic,copy)NSString*ttt;

@end

#import"UILabel+cataary.h"

#import

@implementationUILabel (cataary)

NSString* hhaa;

- (void)setTtt:(NSString*)ttt {

objc_setAssociatedObject(self, &hhaa, ttt,OBJC_ASSOCIATION_COPY_NONATOMIC);

}

- (NSString*)ttt {

returnobjc_getAssociatedObject(self, &hhaa);

}

+ (void)load {

Methodm1 =class_getInstanceMethod(self,@selector(setText:));

Methodm2 =class_getInstanceMethod(self,@selector(sethaha:));

method_exchangeImplementations(m1, m2);

}

- (void)sethaha:(NSString*)haha {

haha=@"999999";

[selfsethaha:haha];

}

@end

相关文章

网友评论

      本文标题:runtime理解笔记

      本文链接:https://www.haomeiwen.com/subject/qisurttx.html