使用运行时函数实现方法交换

通过objc/runtime.h函数库,可以做一些比较有趣的修改,比如平常在使用[UIImage imageNamed:]方法时,即便图片字符串名称填写错误,程序编译或运行时系统都不会提示出错。此处给原方法添加一个小改动,当image为nil时,使用NSLog打印输出台的方式提醒“加载失败”

  • 解决方法一:创建UIIimage的子类,重写[UIImage imageNamed:]方法
    缺点:所有的加载图片都必须要使用自己的类,而且如果是在旧版本上进行迭代,要是修改地方比较多的话会很蛋疼

  • 解决方法二:使用分类为UIIimage类添加一个新方法
    缺点:每次加载图片时,都需要导入分类,而且需要系统方法会被干掉,需要自己实现方法(分类中无法调用super)

  • 解决方法三:使用<objc/runtime.h>中的method_exchangeImplementations实现两个方法之间的交互实现
#import "UIImage+myImageNamed.h"
#import <objc/runtime.h>
@implementation UIImage (myImageNamed)
+(void)load
{
    //获取自带方法
    Method imageNamed = class_getClassMethod(self, @selector(imageNamed:));
    //获取分类添加的方法
    Method myImageNamed = class_getClassMethod(self, @selector(myImageNamed:));
    //交换实现
    method_exchangeImplementations(myImageNamed, imageNamed);
    [super load];
}

+(UIImage *)myImageNamed:(NSString *)name
{
    //1.加载图片
    UIImage *image = [UIImage myImageNamed:name];
    if (image == nil) {
        NSLog(@"加载失败");
    }
    return image;
}
@end

好处:无须在原项目文件在import分类,也无须修改原方法名,即在不对原代码进行任何修改的基础,仅需添加分类方法即可实现原系统方法的改进

posted on 2015-12-30 23:40  夏鲁鲁  阅读(457)  评论(0编辑  收藏  举报