开发过程中,我们经常会用到系统类,而它提供的方法又不能完全满足我们开发的需要,那么在此时,我们需要为系统自带的方法扩展一些功能,而且还要保证原有的功能可正常使用.假设咱们现在有这么一个需求,我们在调用系统的[UIImage imageNamed:@"runtime"];的时候,我们并不能判断有没有加载成功,所以我们想在加载图片的时候并判断是否加载成功。

方案1:

我们通常想到的就是分类,用分类添加一个方法,实现,然后在想要调用的地方导入头文件,去调用.

#import <UIKit/UIKit.h>

@interface UIImage (Method)

+(UIImage *)cdm_imageNamed:(NSString *)imageName;

@end

+(UIImage *)cdm_imageNamed:(NSString *)imageName
{
//首先加载图片
UIImage *image=[UIImage imageNamed:imageName]; //然后实现功能【判断是否为空】 if (image==nil) {
NSLog(@"图片为空");
}
return image;
}

调用:

import "ViewController.h"
#import "UIImage+Method.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; //分类实现:
UIImage *image = [UIImage cdm_imageNamed:@"cdm"]; }

方案2:

利用runtime交换方法,我们调用系统的方法 实际是调用我们的方法:

步骤1.在分类加载的时候+(void)load;交换方法的实现

步骤2.方法交换之前首先获取方法,因为交换方法的两个参数就是方法

步骤3.方法交换

+(void)load
{
// 交换方法实现,方法都是定义在类里面
// class_getInstanceMethod:获取对象
// class_getClassMethod:获取类方法
// IMP:方法实现 // imageNamed
// Class:获取哪个类方法
// SEL:获取方法编号,根据SEL就能去对应的类找方法 Method imageMethod = class_getClassMethod([UIImage class], @selector(imageNamed:)); Method cmd_imageMethod = class_getClassMethod([UIImage class], @selector(cdm_imageNamed:)); //方法交换
method_exchangeImplementations(imageMethod, cdm_imageMethod);
}

如果此时你认为完事了,调用系统的imageNamed方法,会造成死循环。因为我们在自定义的方法中加载图片调用的就是系统的imageNamed的方法,此时应该修改代码如下:

//运行时

+(UIImage *)cdm_imageNamed:(NSString *)imageName
{
//修改为我们自己的方法,防止死循环
UIImage *image=[UIImage cdm_imageNamed:imageName]; //然后实现功能【判断是否为空】
if (image==nil) {
NSLog(@"图片为空");
}
return image;
}

调用实现:

- (void)viewDidLoad {
[super viewDidLoad]; //分类实现:
// UIImage *image = [UIImage cdm_imageNamed:@"cdm"]; //运行时实现:
//调用imageNamed:实际上是调用cdm_imageNamed:
UIImage *image = [UIImage imageNamed:@"cdm"]; }

效果图:

Demo地址:https://github.com/domanc/Method_Exchange.git

快速上手Runtime(三)之方法交换的更多相关文章

  1. 快速上手Runtime(四)之动态添加方法

    如果一个类方法非常多,加载类到内存的时候也比较耗费资源,可以使用动态给某个类,添加方法解决.做到优化内存,节省资源的效果. // // Person.m // ResolveInstanceMetho ...

  2. 让你快速上手Runtime(转)

    前言 本篇主要介绍Runtime在开发中的一些使用场景,顺便讲解了下MJExtension的底层实现.如果喜欢我的文章,可以关注我微博:袁峥Seemygo,也可以来小码哥,了解下我们的iOS培训课程. ...

  3. vuex 快速上手,具体使用方法总结(含使用例子)

    网上有关vuex的文章很多,但有些比较复杂,这篇文章能让你快速使用vuex: vuex 用处:管理全局状态(类似全局变量,每个组件都能访问到) vuex 用法: //下面是一个js文件,用最简单最全的 ...

  4. 快速上手Runtime(二)之给分类添加属性

    我们都知道,分类是不能直接添加属性的,那么我们有时候又需要实现这个功能,那么我们应该怎么办才能为分类添加上属性呢. Runtime给分类添加属性原理 给一个类声明属性,其实本质就是给这个类添加关联,并 ...

  5. 快速上手Runtime(一)之消息机制

    Runtime简介 Runtime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C语言,函数的调用在编译的时候会决定调用哪个函数. 对于OC的函数,属于动态 ...

  6. 如何快速上手一个新技术之vue学习经验

    碰到紧急项目挪别人的vue项目过来直接改,但是vue是18年初看过一遍,18年底再来用,早就忘到九霄云外了,结果丢脸的从打开vue开始学,虽然之前在有道云笔记做了很多记录,然后没有系统整理.所以借这次 ...

  7. C/ C++ 快速上手

    C++ 快速上手 (一)https://www.cnblogs.com/cosmo89929/archive/2012/12/22/2828745.html C++ 快速上手 (二)https://w ...

  8. 三分钟快速上手TensorFlow 2.0 (下)——模型的部署 、大规模训练、加速

    前文:三分钟快速上手TensorFlow 2.0 (中)——常用模块和模型的部署 TensorFlow 模型导出 使用 SavedModel 完整导出模型 不仅包含参数的权值,还包含计算的流程(即计算 ...

  9. EF Core 快速上手——EF Core的三种主要关系类型

    系列文章 EF Core 快速上手--EF Core 入门 本节导航 三种数据库关系类型建模 Migration方式创建和习修改数据库 定义和创建应用DbContext 将复杂查询拆分为子查询   本 ...

随机推荐

  1. 如何点焊过的镍片再次焊接到 PCBA 上?

    如何将点焊过的镍片再次焊接到 PCBA 上? 在 PCBA 上贴了镍片再点焊,这样的制造工艺可以大大减少人工处理,提高生产通过率. 由于种种原因,有些机器可能有故障需要维修,而且电池又需要拆下来,才能 ...

  2. 关于ng-class,ng-style的用法

    ng-class的使用几种方式 (1):利用双向数据绑定(className根据chang2的值去匹配类) <div class="{{className}}">... ...

  3. redis+php微博功能的redis数据结构设计总结(四)

    概述: 1.完全采用redis作为数据库实现微博的登录2.发布3.微博的显示4.实现整个功能使用了redis的string,list,hashes四个数据类型,以及string类型的数值自增功能 一. ...

  4. Js、jquery学习笔记

    end() 方法 重新定位到上次操作的元素,一般与siblings()一起使用,操作其兄弟元素.如:$(this).addClass("highlight").children(& ...

  5. Unit02: JSON 、 使用JSON实现数据交换 、 jQuery对AJAX的支持,编码问题

    Unit02: JSON . 使用JSON实现数据交换 . jQuery对AJAX的支持 1. 编码问题 (1)发送get请求 为什么会产生乱码? ie浏览器提供的ajax对象,对中文会使用gbk来编 ...

  6. 与FPGA相关的独热码

    独热码在状态机里面使用比价广泛,这一块有些人爱用,有些人嫌烦,有时候可以用用格雷码跳转,不过格雷码只支持那种一步到底的,中间有分支就不好做了,所以后来还是回到了独热码的正道上. 说白了独热码的使用,在 ...

  7. idea maven 打包 引用本地jar

    1将本地jar包导入到mvn本地库 mvn install:install-file -Dfile=/Users/liuqiang/Documents/gmpl/gmpl-server/lib/ali ...

  8. 数据结构与算法JavaScript描述——栈的使用

    有一些问题特别适合用栈来解决.本节就介绍几个这样的例子.   1) 数制间的相互转换 可以利用栈将一个数字从一种数制转换成另一种数制.假设想将数字n 转换为以b 为基数的数字,实现转换的算法如下. 使 ...

  9. Linux:数据库服务(Mysql安装及链接、远程链接、genelog)

    yum  search  +  服务:查询服务是否存在: yum  remove  +  服务:卸载服务: 使用 service 操作服务时,服务的名称后要加上字符 d,如启动:service  my ...

  10. 20165226 2017-2018-4 《Java程序设计》第7周学习总结

    20165226 2017-2018-4 <Java程序设计>第7周学习总结 教材学习内容总结 第十一章 JDBC与MySQL数据库 下载MySQL最新版本. 连接数据库 下载JDBC-M ...