runtime交换方法
2018-07-20 本文已影响11人
StoneWing
-
使用场景:
举个例子:UIImage imageNamed:@"",我们需要知道它返回的image对象是否为空?
-
一般的做法
- 新建一个UIImage的扩展类,比如:UIImage+Named;
- 新建一个类方法: wsl_imageNamed
+ (UIImage *)wsl_imageNamed:(NSString *)imageName {
UIImage *image = [UIImage imageNamed:imageName];
if (imageName == nil) {
NSLog(@"图片为空");
}
return image;
}
- 在需要的地方,我们倒入包:#import "UIImage+Named.h"
- 使用:UIImage *image = [UIImage wsl_imageNamed:@"123"];
注:这么做的弊端
- 没次使用的时候需要倒入UIImage+Named.h头文件
- 如果项目本身已经存在,过了一段时间有需求需要改动的时候,就需要每个地方去改动
-
runtime做法
- 一样的新建UIImage的扩展类
- 同样的我们创建类方法: wsl_imageNamed
+ (UIImage *)wsl_imageNamed:(NSString *)imageName {
UIImage *image = [UIImage imageNamed:imageName];
if (imageName == nil) {
NSLog(@"图片为空");
}
return image;
}
- 做交换:是系统的imageNamed和wsl_imageNamed方法交换(在load方法中进行)
+ (void)load {
// 获取系统的imageNamed方法
Method imageNamedMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
// 获取自定义的方法
Method wsl_imageNamedMethod = class_getClassMethod([UIImage class], @selector(wsl_imageNamed:));
// 交换
method_exchangeImplementations(imageNamedMethod,wsl_imageNamedMethod);
}
注意: 因为我们把系统的方法和自定义的方法进行了交换,所以我们自定义的方法需要进行写修改
+ (UIImage *)wsl_imageNamed:(NSString *)imageName {
// 因为方法已经交换,所以调用的imageNamed方法其实是调用的wsl_imageNamed,会进入死循环
// UIImage *image = [UIImage imageNamed:imageName];
// 修改为 wsl_imageNamed
UIImage *image = [self wsl_imageNamed:imageName];
if (imageName == nil) {
NSLog(@"图片为空");
}
return image;
}
- 使用:UIImage *image = [UIImage imageNamed:@"123"];
这里不需要倒入头文件:UIImage+Named: