美文网首页
Runtime从零学起(一)

Runtime从零学起(一)

作者: danson | 来源:发表于2018-03-29 15:34 被阅读10次

    写在前边的话:打算开始写个系列学习笔记,不喜勿喷!!!!

    由于项目需要,先学习了利用Runtime实现方法互换从而扩充功能,学习中与类目(分类)做了个对比,一并写出来,看官勿怪....

    Runtime的各种原理一搜一大堆,这里就不command+V了,直接上代码

    这个demo的目的是在利用name加载图片后,获取是否加载成功,不成功做些记录或其他操作,给UIImage添加个分类也很容易实现,这次真的上代码了

    分类实现

    分类.h文件

    @interface UIImage (LoadResult)

    //先用类别实现 给系统类添加方法 缺点:所有用到的地方都需要导入分类的头文件并且修改方法 如果是给已经存在的项目扩充某功能 能把”C“、“V”键给摁坏

    +(UIImage *)imageWithName:(NSString *)name;

    @end

    分类.m文件

    @implementation UIImage (LoadResult)

    //用类别实现

    +(UIImage *)imageWithName:(NSString *)name {

        UIImage *image = [UIImage imageNamed:name];//原功能

        //新增功能

        if (image) {

            NSLog(@"图片%@加载成功!",name);

        }else {

            NSLog(@"图片%@加载失败!",name);

        }

        return image;

    }

    @end

    分类的使用:

    #import "UIImage+LoadResult.h" //每个用到的地方都要导入 也可以放在.pch中

    UIImageView *imageView1 = [[UIImageView alloc] init];

    imageView1.image = [UIImage imageWithName:@"banner"];//只能用新的方法

    [self.view addSubview:imageView1];

    imageView1.sd_layout.leftSpaceToView(self.view, 20).rightSpaceToView(self.view, 20).topSpaceToView(self.view, 100).heightIs(80);

    UIImageView *imageView2 = [[UIImageView alloc] init];

    imageView2.image = [UIImage imageWithName:@"hahahabucunzai"];

    [self.view addSubview:imageView2];

    imageView2.sd_layout.leftSpaceToView(self.view, 20).rightSpaceToView(self.view, 20).topSpaceToView(imageView1, 80).heightIs(80);

    打印结果:

    OK,目的达成 接下来,用Runtime将方法调换,没错终于到正题了

    Runtime实现

    #import <objc/runtime.h> //导入runtime相关的类

    //load方法在加载分类至内存的时候调用 方法的交换要在消息传递之前

    +(void)load {

        //获取imageNamed方法实现地址

        Method imageNamed = class_getClassMethod(self, @selector(imageNamed:));

        //获取imageWithName方法实现地址

        Method imageWithName = class_getClassMethod(self, @selector(imageWithName:));

        //交换imageNamed和imageWithName方法实现地址 从而达到实现交换方法实现的目的

        method_exchangeImplementations(imageNamed, imageWithName);

    }

    //实现用来替换imageNamed:的方法

    +(UIImage *)imageWithName:(NSString *)name {

        //获取照片 这个地方要调用imageWithName  因为imageWithName和imageNamed已经互换了 当分类加载至内存的时候 这种交换关系就已经确定了

        UIImage *image = [UIImage imageWithName:name];

        //添加功能

        if (image) {

            NSLog(@"图片%@加载成功!",name);

        }else {

            NSLog(@"图片%@加载失败!",name);

        }

        return image;

    }

    加载图片调用:

    UIImageView *imageView1 = [[UIImageView alloc] init];

    imageView1.image = [UIImage imageNamed:@"banner"];//这时候直接用imageNamed:

     [self.view addSubview:imageView1];

    imageView1.sd_layout.leftSpaceToView(self.view, 20).rightSpaceToView(self.view, 20).topSpaceToView(self.view, 100).heightIs(KWidth/4.0);

    UIImageView *imageView2 = [[UIImageView alloc] init];

    imageView2.backgroundColor = [UIColor magentaColor];

    imageView2.image = [UIImage imageNamed:@"hahahabucunzai"];

    [self.view addSubview:imageView2];

    imageView2.sd_layout.leftSpaceToView(self.view, 20).rightSpaceToView(self.view, 20).topSpaceToView(imageView1, 80).heightIs(KWidth/4.0);

    打印结果:

    上边的是其他页面用到的图片,并未特意做操作,但也调用到了交换后的方法,就是这么随意0.0

    OK,到此结束!感谢诸位看官,欢迎指导交流。

    相关文章

      网友评论

          本文标题:Runtime从零学起(一)

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