02 runtime用法之交换方法

作者: 小码码 | 来源:发表于2017-03-24 18:05 被阅读20次

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方法;

相关文章

网友评论

    本文标题:02 runtime用法之交换方法

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