1 方法调用机制
- 本质是让对象发送消息.对象方法保存到类中,每个类都有一个方法列表
- (1)根据对象的isa指针找到对应的类
- (2)根据方法编号查找到方法名
- (3)根据方法名找到函数实现,方法名就是函数入口
2 交换方法的实现机制
3 交换方法使用举例
场景: 有个项目,已经开发2年多了,之前加载图片都是用UIImage,忽然有一天,老大说给我写一个加载图片方法,判断是否成功加载图片
常用思路:
- (1)直接添加判断
// 1.加载图片
UIImage *image = [UIImage imageNamed:@"abc"];
// 2.判断
if (image) {
NSLog(@"加载成功");
} else {
NSLog(@"加载失败");
}
备注:封装性不好,到处都需要写判断代码
(2)分类中重写系统的imageNamed(不推荐,会把系统方法覆盖掉)
(3)自定义image
创建一个继承自UIImage的类,实现方法:
+ (UIImage *)imageNamed:(NSString *)name
{
// 加载图片
// super:UIImage
UIImage *image = [super imageNamed:name];
if (image) {
NSLog(@"加载成功");
} else {
NSLog(@"加载失败");
}
return image;
}
备注:只能在后期开发过程中使用,如果之前图片加载的地方都要做判断,需要把所有的UIImage换成自定义的MyImage,工作量大.
- (4)runtime交换方法实现(推荐)
1.创建一个UIImage的分类,自定义my_imageNamed方法
+ (UIImage *)xmg_imageNamed:(NSString *)name
{
// 1.加载图片
UIImage *image = [UIImage xmg_imageNamed:name];
// 2.判断
if (image) {
NSLog(@"加载成功");
} else {
NSLog(@"加载失败");
}
return image;
}
2. 在load方法中实现方法交换
// 保证在所有方法之前交换,只会调用一次
+ (void)load
{
// 获取imageName方法
Method imageNamedMethod = class_getClassMethod(self, @selector(imageNamed:));
// 获取MY_imageNamed方法(自定义的方法)
Method my_imageNamedMethod = class_getClassMethod(self, @selector(my_imageNamed:));
// 利用runtime交换方法
method_exchangeImplementations(imageNamedMethod, my_imageNamedMethod);
}
备注:交换以后,调用imageNamed方法,实质实现的是my_imageNamed方法;调用my_imageNamed方法,实质实现的是imageNamed方法;