关闭

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

标签: objective-c
242人阅读 评论(0) 收藏 举报
分类:

原地址: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

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:13125次
    • 积分:397
    • 等级:
    • 排名:千里之外
    • 原创:25篇
    • 转载:0篇
    • 译文:3篇
    • 评论:0条
    文章分类