http://www.cocoachina.com/ios/20150717/12623.html

可能大家一直看到有许多朋友在Runtime相关文章中介绍IMP指针的概念,那么IMP究竟有什么实际作用呢?让我们先从一个函数看起来。

Method Swizzling

如果对Runtime有一定了解的话,一定听说过或者用过这个函数:

1
void method_exchangeImplementations(Method m1, Method m2)

它通常叫做method swizzling,算是ObjC的"黑魔法"了,作用就是在程序运行期间动态的给两个方法互换实现,比如有这样一种使用场景:

我们的程序中有许多个ViewController,我想在对项目改动最小的情况下,在当每个Controller执行完ViewDidLoad以后就在控制台把自己的名字打印出来,方便我去做调试或者了解项目结构。

有许多朋友会这样说,让所有控制器都继承一个BaseController不就可以了吗?我在这里要解释一下这样做的缺点:假如你的项目里有许多Controller的话,你就需要把项目里凡是没有继承自BaseController的每个Controller都做一次修改了,而且随意更改层级结构会发生意想不到的错误。

其实我们的目的就是重写ViewDidLoad的方法,并在他的方法最后加上几句Log,所以我们需要给UIViewController建立一个category,因为我们知道,如果在Catagory中重写一个方法,就会覆盖它的原有方法实现,但是,这样做以后就没有办法调用系统原有的方法,因为在一个方法里调用自己的方法会是一个死循环。所以我们的解决办法就是,另外写一个方法来和viewDidLoad“交换”,这样外部调用viewDidLoad就会调到新建的这个方法中,同样,我们调用新建的方法就会调用到系统的viewDidLoad中了。

IMP指针

其实,还有一种更加简单的方法可以让我们办到相同的目的,运用IMP指针,IMP就是Implementation的缩写,顾名思义,它是指向一个方法实现的指针,每一个方法都有一个对应的IMP,所以,我们可以直接调用方法的IMP指针,来避免方法调用死循环的问题。

调用一个IMP的方式和调用普通C函数相同,比如:

1
id returnObjc = someIMP(objc,SEL,params...);

不过如果你的项目没有做其他配置的话这样调用编译器是不会通过的,我们来看一下先它的定义:

1
2
3
4
5
if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ ); 
else
typedef id (*IMP)(id, SEL, ...); 
endif

在默认情况下你的工程是打开这个配置的

这种情况下IMP被定义为无参数无返回值的函数。所以你需要到工程里搜索到这个选项并把它关闭。这样的麻烦就是,每次使用,你都需要修改工程配置,所以这里我再介绍另外一种办法:重新定义一个和有参数的IMP指针相同的指针类型,在获取IMP时把它强转为此类型。这样运用IMP指针后,就不需要额外的给ViewController写新的方法:

还有一个地方我们需要注意,如果这样直接调用IMP的话就会发生经典的EXC_BAD_ACCESS错误,我们定义的IMP指针是一个有返回值的类型,而其实我们获取的viewDidLoad这个方法是没有返回值的,所以我们需要新定义一个和IMP相同类型的函数指针比如VIMP,把他的返回值定位Void,这样如果你修改的方法有返回值就用IMP,没有返回值就用VIMP。

值得注意的是,如果你重写的方法有返回值,不要忘记在最后做return。

总结

实际上直接调用一个方法的IMP指针的效率是高于调用方法本身的,所以,如果你有一个合适的时机获取到方法的IMP的话,你可以试着调用它。

这是只是IMP使用的场景之一,它还有许多作用,希望大家多多发现。

轻松学习之 IMP指针的作用的更多相关文章

  1. 轻松学习之三——IMP指针的作用

    http://www.jianshu.com/p/425a39d43d16 可能大家一直看到有许多朋友在Runtime相关文章中介绍IMP指针的概念,那么IMP究竟有什么实际作用呢?让我们先从一个函数 ...

  2. ios -- 教你如何轻松学习Swift语法(二)

    前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦.      一.可选类型(重点内容)   1.什么是可选类型?        1.1在OC开 ...

  3. IMP指针

    可能大家一直看到有许多朋友在Runtime相关文章中介绍IMP指针的概念,那么IMP究竟有什么实际作用呢?让我们先从一个函数看起来. Method Swizzling 如果对Runtime有一定了解的 ...

  4. 轻松学习LINUX系列教程推出

    本系列多媒体教程已完成的博文: 1.轻松学习Linux之入门篇 http://chenguang.blog.51cto.com/350944/449214 2.轻松学习Linux之本地安装系统 (分区 ...

  5. 轻松学习JavaScript十八:DOM编程学习之DOM简单介绍

    一DOM概述 DOM(文档对象模型)是HTML和XML的应用程序接口(API).DOM将把整个页面规划成由节点层级构成的文档. DOM描绘了一个层次化的节点树,执行开发者加入,移除和改动页面的某一部分 ...

  6. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  7. 轻松学习Linux之Shell文件和目录属性详解

    轻松学习Linux之Shell文件和目录属性详解 轻松学习Linux之理解Sitcky 轻松学习Linux之理解umask 轻松学习Linux之理解SUID&SGUID 本系列多媒体教程已完成 ...

  8. 轻松学习RSA加密算法原理 (转)

    轻松学习RSA加密算法原理 (转) http://blog.csdn.net/q376420785/article/details/8557266 http://www.ruanyifeng.com/ ...

  9. C++学习之函数指针

     C++学习之函数指针          和数据项类似,函数也有地址,函数的地址是存储在机器语言代码的内存的开始地址.通常,这些地址对用户而言,不重要也没什么用处,但对程序而言,它却很有用. 一.函数 ...

随机推荐

  1. loading遮罩

    .loading{ position: relative; cursor: default; point-events: none; text-shadow: none!important; colo ...

  2. Visifire For WPF 图表控件 如何免费

    可能用WPF生成过图表的开发人员都知道,WPF虽然本身的绘图能力强大,但如果每种图表都自己去实现一次的话可能工作量就大了, 尤其是在开发时间比较紧的情况下.这时候有必要借助一种专业的图表工具. Vis ...

  3. python元祖和列表

    下面讲到的分别有: 列表:元祖 列表的定义 list(列表)是python中使用最频繁的数据类型,在其他语言中叫做数组 专门储存一串信息 列表[  ]定义,数据之间有逗号分隔 列表的索引是从0开始的 ...

  4. vue前后端分离

    axios前后端交互 安装 一定要安装到`项目目录下 cnpm install axios 配置 在main.js中配置 //配置axios import axios from 'axios' Vue ...

  5. Spring Boot邮件功能

    1.应用场景 邮件功能的应用场景可谓十分广泛,诸如注册用户.密码找回,消息通知.以及一些程序异常通知等都需要使用到该功能. 正是由于邮件功能的使用广泛,因此springboot也加在它的组件中添加了邮 ...

  6. Codeforces 1150D(字符串dp)

    反思 三维的dp压根没看出来,看题解以后思路又很直观,找几道字符串dp练练才行 序列自动机和优化一维略 /* __ __ * ____| |_____| |____ * | | * | __ | * ...

  7. windows下maven的安装配置

    什么是maven Maven是基于POM(工程对象模型),通过一小段描述来对项目的代码.报告.文件进管理的工具. Maven是一个跨平台的项目管理工具,它是使用java开发的,它要依赖于jdk1.6及 ...

  8. 2019阿里云开年Hi购季基础云产品分会场全攻略!

    2019阿里云云上Hi购季活动已经于2月25日正式开启,从已开放的活动页面来看,活动分为三个阶段: 2月25日-3月04日的活动报名阶段.3月04日-3月16日的新购满返+5折抢购阶段.3月16日-3 ...

  9. excel怎么并排查看两个工作表

    excel怎么并排查看两个工作表 excel怎么并排查看两个工作表?excel打开一个窗口想要同时查看两个工作表中的数据,类似于word中的分栏效果,该怎么实现呢?EXCEL是一个使用最多的办公软件, ...

  10. Android——app基础

    Android Application基础 系统启动过程 APK文件介绍 APK是Android Package的缩写,即android安装包.APK 文件其实是zip 格式,但后缀名被修改为apk  ...