runtime交换方法

  • 使用场景:

    举个例子: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:

你可能感兴趣的:(runtime交换方法)