runtime(交换两个方法的实现,拦截系统自带方法调用功能)

2016-11-28  本文已影响0人  握青春

导入<objc/runtime.h>

1. 获得某个类的类方法

Method m1 = class_getClassMethod(Class cls , SEL name)

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

Method m2 = class_getInstanceMethod(Class cls , SEL name)

3. 交换两个方法

 method_exchangeImplementations(Method m1 ,

Method m2)

暂时没用到,用网上的一个栗子:

创建一个Dog类,

+ (void)eat {

NSLog(@"eat");

}

+ (void)run {

NSLog(@"run");

}

[Dog eat]; [Dog fuck]; 先吃后跑,使用

Method m1 = class_getClassMethod(Dog Class ,@selector(eat));

Method m2 = class_getClassMethod(Dog Class ,@selector(eat));

method_exchangeImplementations(m1, m2);// 交换后,先打印学习,再打印跑!

 [Dog eat]; [Dog fuck];

案例2:

系统的拦截方法:(比较老的例子)

iOS6和iOS7扁平和拟物化加载扁平和拟物风格, 不通过手动一个个修改imageNamed 就可以加入版本判断语句.(这句话没懂)

新建 UIImage + Category,

在分类中实现一个自定义的方法,加入你的需求,比如

+ (UIImage *)xl_imageNamed:(NSString *)name {

double version = [[UIDevice currentDevice].systemVersion doubleValue]; 

if (version >= 7.0) { 

 // 如果系统版本是7.0以上,使用另外一套文件名结尾是‘_os7’的扁平化图片          name = [name stringByAppendingString:@"_os7"];

}

return [UIImage xh_imageNamed:name]; 

// 调用一下系统的方法让其有原来方法的功能,因为已经交换过,所以显示的是新的方法

}

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

+ (void)load { 

 // 获取两个类的类方法    

  Method m1 = class_getClassMethod([UIImage class],  @selector(imageNamed:));     

 Method m2 = class_getClassMethod([UIImage class],  @selector(xh_imageNamed:)); 

// 开始交换方法实现     

 method_exchangeImplementations(m1, m2); 

}

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

// 这句话要好好理解,可以增加自己思路广度

上一篇 下一篇

猜你喜欢

热点阅读