美文网首页runtimeiOSiOS开发常用知识点
runtime简单使用之方法的交换

runtime简单使用之方法的交换

作者: Alexander | 来源:发表于2016-03-08 20:29 被阅读2232次

一, 使用runtime实现方法的交换

一, 前言

  • 在开发过程中,我们常常会遇到一种问题: 即当我们使用系统自带的方法时,发现系统方法的功能不能满足我们的需求,这时候需要我们给系统的方法添加额外的功能.

  • 下面以一个例子来实现给系统自带的方法添加额外的功能.

  • 项目背景 : 公司有个开发了很久的项目,之前使用添加图片的方法用的是:imageName:方法, 现在的项目需求是给系统自带的imageName:添加一个功能:如果下载的图片不存在,那么就提示我们当前下载的图片为空.

  • 思路 : 给系统自带的方法添加功能的几种方法

    • 1, 自定义类, 重写系统自带的imageName:方法,这种方法虽然可以实现,但是它的弊端就是必须要使用自己的类,依赖性强.
    • 2, 个UIImage添加一个分类, 改变系统类的实现,给系统的类添加方法的时候调用(强烈不推荐)
    • 3, 使用runtime的交互方法,给系统的方法添加功能. 具体实现 : 添加一个分类 --> 在分类中提供一个需要添加的功能的方法 --> 将这个方法的实现和系统自带的方法的实现交互.

二, 步骤

  • 1, 新建一个继承自UIImage的分类,定义一个方法实现给系统的自带的方法添加功能.
#import <UIKit/UIKit.h>

@interface UIImage (WGImage)

// 声明方法
// 如果跟系统方法差不多功能,可以采取添加前缀,与系统方法区分
+ (UIImage *)wg_imageWithName:(NSString *)imageName;

@end

  • 2, 实现方法的交互

 定义完毕新方法后,需要弄清楚什么时候实现与系统的方法交互?
 答 : 既然是给系统的方法添加额外的功能,换句话说,我们以后在开发中都是使用自己定义的方法,取代系统的方法,所以,当程序一启动,就要求能使用自己定义的功能方法.说道这里:我们必须要弄明白一下两个方法 :
 +(void)initialize(当类第一次被调用的时候就会调用该方法,整个程序运行中只会调用一次)
 + (void)load(当程序启动的时候就会调用该方法,换句话说,只要程序一启动就会调用load方法,整个程序运行中只会调用一次)


+ (void)load {
/*
     self:UIImage
     谁的事情,谁开头 1.发送消息(对象:objc) 2.注册方法(方法编号:sel) 3.交互方法(方法:method) 4.获取方法(类:class)
     Method:方法名

     获取方法,方法保存到类
     Class:获取哪个类方法
     SEL:获取哪个方法
     imageName
*/
    // 获取imageName:方法的地址
    Method imageNameMethod = class_getClassMethod(self, @selector(imageNamed:));

    // 获取wg_imageWithName:方法的地址
    Method wg_imageWithNameMethod = class_getClassMethod(self, @selector(wg_imageWithName:));

    // 交换方法地址,相当于交换实现方式
    method_exchangeImplementations(imageNameMethod, wg_imageWithNameMethod);

}

  • 3, 加载图片, 判断当前图片是否为空
// 加载图片, 判断是否为空
+ (UIImage *)wg_imageWithName:(NSString *)imageName
{
    // 这里调用imageWithName,相当于调用imageName
    UIImage *image = [UIImage wg_imageWithName:imageName];
    if (!image) {
        NSLog(@"Alex : 图片不存在");
    }
    return image;
}

  • 4, 使用交互后的方法
#import "ViewController.h"
#import "WGStudent.h"
#import "UIImage+WGImage.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

  //  wg_imageWithName ---> imageNamed(底层的操作 : 1, 下载图片. 2, 判断图片是否存在 )
    [UIImage imageNamed:@"WilliamAlex.png"];
}

@end
  • 5, 打印结果
2016-03-08 17:29:50.372 fdsfsdf[1545:96854] Alex : 图片不存在

知识拓展

  • 不能在分类中重写系统方法imageNamed,因为会把系统的功能给覆盖掉,而且分类中不能调用super.

相关文章

  • runtime简单使用之方法的交换

    一, 使用runtime实现方法的交换 一, 前言 在开发过程中,我们常常会遇到一种问题: 即当我们使用系统自带的...

  • runtime基本用法

    先导入 runtime 头文件。1、用 runtime 改变变量值; 2、使用 runtime 交换方法; 3、使...

  • Object-C Runtime交换方法的细节

    runtime不做多的介绍。。。它的作用之一就是交换方法的实现!在交换的时候,会用到的方法: 这里有一个坑meth...

  • runTime常用方法

    使用runTime改变实例成员的值 使用runtime来交换两个方法 注意再次调用该方法不交换 使用runTime...

  • runtime

    runtime交换方法 动态添加方法

  • Runtime应用之交换方法实现

    Runtime一个常用的场景是交换方法的调用。其实就是利用了Runtime的方法交换,具体代码如下: 核心思路是先...

  • Runtime(一)方法交换

    Runtime的常用方法(交换方法) 举个简单的例子就是在我们调用UIImage的imageNamed方法时判断加...

  • Runtime

    runtime运行时机制1:通过runtime,实现方法交换(交换两个类方法、交换两个实例方法)2:通过runti...

  • MethodSwizzle

    新建工程,注入 Framework后,注入简单测试代码,利用 Runtime 特性交换方法

  • Day3

    1 runtime运行时机制1:通过runtime,实现方法交换(交换两个类方法、交换两个实例方法)。2:通过ru...

网友评论

  • 科24:为甚我的不执行 wg_imageWithName内部的判断
  • ca7508dad23b:刚入门时候runtime的理论知识让自己一头雾水,谢谢你简单明了的实际例子。真心感谢!

本文标题:runtime简单使用之方法的交换

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