Objective-C Runtime method swizzling简介(翻译)

翻译 2016年05月31日 23:05:43

原地址:http://community.hpe.com/t5/Software-Developers/Objective-C-Runtime-method-swizzling-in-a-nutshell/ba-p/6122133#.V02N62aAmT8
我的主页:http://yintokey.github.io/2016/05/31/Objective-C-Runtime-method-swizzling%E7%AE%80%E4%BB%8B%EF%BC%88%E7%BF%BB%E8%AF%91/

作为一个开发者,Objective-C让你有改变两个方法实现的能力。换句话说,你可以用一个方法的实现去取代另一个方法的实现。
这里写图片描述

在objective-c 运行时机制中,方法调配是一项已知的技术,可以用它去代替或者扩展那些你没拥有的类方法(包含 iOS\OSX 库)。方法调配本质上是改变了方法名到方法实现的映射,就如上面图所示。

如果你到网上搜Method swizzling,你会找到一大堆文章说它是很危险的技术。我认为方法调配(Method swizzling)和很多编程技术一样,如果你不是十分清楚你所做的事,那么它是有风险且有害的。但是它也可以很有用,我的建议是小心使用且清楚地理解它。

当今,大部分移动功能的自动框架使用调配技术通过调配UIApplication类(以及其它不同类方法)的事件发送方法去实现record-replay功能,所以它们将会控制所有传入iOS运行时机制中的UI事件。

在举例子之前,有一些我认为很重要的点需要看下:
1.如果你决定调配一个方法,我建议你在应用的整个生命周期里去调配它,就是在一开始的时候调配一次,然后一直保持直到应用关闭。
2.最适合方法调配的地方是在 + (void) load 中。因为方法调配很难调试(debug),所以我建议你尽可能地添加日志(logs)。
3.在继承中,方法调配有点棘手。比如B类和C类来源于A类,A类声明了方法Foo1,如果你在B类的load method里去调配Foo1,那么每次从C类中调用 Foo1(显式或隐式),都将会执行调配后的方法实现。因为实际上你已经交换了基类的实现。为了绕过这个问题,你需要添加方法Foo1到B类,而且只有这么做以后,你才可以去调配它。
下面的例子,我给你展示如何在运行时中添加方法,而且提供一些好的关于方法调配的练习。在这个例子中,我假设你对objective-c的类别很熟悉。

我们要做的是用日志(log)记录下当用户与屏幕交互时所有应用接收到的 UI事件和点击,基于这个,我们将会调配UIApplication类方法中的sendEvent
objc/runtime.h中,有少数API用到了调配方法
1- class_getInstanceMethod(Class cls, SEL selector);
2- method_exchangeImplementations(SEL origin, SEL newSel);
3- class_addMethod

我们需要做4个步骤:
1.创建一个UIApplication类的类别,
2.添加新方法swizzleMethod:
我们需要做4个步骤:
1.创建一个UIApplication类的类别,
2.添加新方法swizzleMethod:
这里写图片描述
在调配之前,我们添加了原始的方法给self来避免我们上面所讨论的继承问题,只有在这之后我们才交换方法的实现。

3.添加一个新方法swizzeledSendEvent,如下
这里写图片描述
在方法实现中没有递归调用,因为调用swizzeledSendEvent 将会执行初始sendEvent方法的实现。

4.实现+(void) load 方法,加入下面代码:
这里写图片描述
每次iOS 运行时系统调用UIApplication类的sendEvent方法,swizzeledSendEvent都会被触发。而且在我们的方法实现中,我们会再次调用swizzeledSendEvent 。 这并不是递归调用,因为当我们调用swizzeledSendEvent. 它在初始sendEvent的方法实现都会被执行。

作者:Ameer Tabony

Objective-C Runtime :Method Swizzling - method_exchangeImplementations

http://southpeak.github.io/blog/2014/11/06/objective-c-runtime-yun-xing-shi-zhi-si-:method-swizzling...
  • jeffasd
  • jeffasd
  • 2016年08月01日 11:57
  • 162

Objective-C Runtime(四)Method Swizzling

Objective-C对象收到消息之后,究竟会调用何种方法需要在运行期间才能解析出来。那你也许会问:与给定的选择子名称相应的方法是不是也可以在runtime改变呢?没错,就是这样。若能善用此特性,则可...
  • xsh841272293
  • xsh841272293
  • 2017年09月19日 10:04
  • 123

Objective-C Runtime 运行时:Method Swizzling

原文出处: 南峰子的技术博客    理解Method Swizzling是学习runtime机制的一个很好的机会。在此不多做整理,仅翻译由Mattt Thompson发表于nshipster的M...
  • wqt925497045
  • wqt925497045
  • 2016年04月08日 11:14
  • 222

Objective-C Runtime Programming Guide 中文翻译

介绍Objective-C将许多决策从便宜时期和链接时期延后到运行时期。只要可能,它都动态的做很多事情。这意味着它不仅需要一个编译器,还需要一个运行时系统来执行编译好的代码。对于Objective-C...
  • syd_programming
  • syd_programming
  • 2016年05月16日 22:10
  • 4272

Method Swizzling的方法

开发中总会遇到需要使用Method Swizzling的时候,记录一下Method Swizzling的正确方法一、方法以hookUIViewController 为例#import @impleme...
  • sinat_25544827
  • sinat_25544827
  • 2017年01月17日 12:01
  • 461

iOS运行时与method swizzling

iOS中method swizzling的介绍
  • sakulafly
  • sakulafly
  • 2014年05月29日 22:36
  • 8404

method-swizzling 详解 和使用

简介在Objective-C中调用一个方法,其实是向一个对象发送消息,查找消息的唯一依据是selector的名字。利用Objective-C的动态特性,可以实现在运行时偷换selector对应的方法实...
  • Erice_e
  • Erice_e
  • 2017年06月15日 16:53
  • 513

Objective-C Runtime 运行时之:Method Swizzling

Method Swizzling是改变一个selector的实际实现的技术。通过这一技术,我们可以在运行时通过修改类的分发表中selector对应的函数,来修改方法的实现。例如,我们想跟踪在程序中每一...
  • jamy08
  • jamy08
  • 2015年12月29日 17:25
  • 255

Method Swizzling中的陷阱

这篇文章不是介绍什么是方法交换,这类文章很多,如果你不知道什么是方法交换可以看这篇文章:Method Swizzling...
  • dp948080952
  • dp948080952
  • 2017年02月05日 19:55
  • 352

ios学习路线—Objective-C(Runtime Method Swizzling)

Method Swizzling是改变一个selector的实际实现的技术。通过这一技术,我们可以在运行时通过修改类的分发表中selector对应的函数,来修改方法的实现。 例如,我们想跟踪在程序中...
  • dubo413392749
  • dubo413392749
  • 2016年06月17日 00:27
  • 81
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Objective-C Runtime method swizzling简介(翻译)
举报原因:
原因补充:

(最多只允许输入30个字)