OC · 记——Runtime(二)交换方法

交换方法

交换方法:使用场景:系统自带的功能不够,给系统自带的方法扩展一些功能,并且保持原有的功能。
方式1:继承系统的类,重写方法
方式2:使用runtime交换方法

例如:我们现在要在控制器中加载一张图片。

//用这个方法加载图片,并不知道图片是否加载成功
UIImage *img = [UIImage imageNamed:@"111"];

一般的做法,我们会给UIImage创建一个分类,先创建一个分类:UIImage+img,然后重新写一个类方法,来判断是否加载成功。

+ (__kindof UIImage *)home_imageNamed:(NSString *)imageName;
+ (__kindof UIImage *)home_imageNamed:(NSString *)imageName
{
    //1.加载图片
    UIImage *img = [UIImage imageNamed:imageName];
    //2.判断功能
    if (img == nil) {
        NSLog(@"加载图片为空");
    }
    return img;
}

这样子,在控制器中,引入分类头文件,#import "UIImage+img.h",直接调用,可以实现判断是否加载成功。
但是,我们每次使用这个方法的时候,都需要导入头文件。现在我们通过runtime来实现调用imageNamed,底层调用:home_imageNamed。

在分类中,引入runtime头文件 #import <objc/message.h>
加载分类时调用load方法。

//加载这个分类的时候调用
//交换方法实现,方法都是定义在类里面
+ (void)load
{
    NSLog(@"%s",__func__);
    /*
     Class:获取哪个类方法
     SEL:获取方法编号,根据SEL就能去对应的类找方法
     */
   Method imageNamedMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
    //home_imageNamed
   Method home_imageNamedMethod = class_getClassMethod([UIImage class], @selector(home_imageNamed:));
    
    //交换方法
    method_exchangeImplementations(imageNamedMethod, home_imageNamedMethod);
    
}
//由于运行程序就会调用load,现在交换方法成功。
//在这个方法中,加载图片,得用home_imageNamed
+ (__kindof UIImage *)home_imageNamed:(NSString *)imageName
{
    //1.加载图片
    UIImage *img = [UIImage home_imageNamed:imageName];
    //2.判断功能
    if (img == nil) {
        NSLog(@"加载图片为空");
    }
    return img;
}

现在交换方法写好了,我们在控制器中不需要引入分类头文件,直接调用imageNamed,运行程序。

2017-01-18 13:20:47.549 [73546:6523190] +[UIImage(img) load]
2017-01-18 13:20:47.596 [73546:6523190] 加载图片为空
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容