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

本文转自南峰子的技术博客

Objective-C Runtime 运行时之四:Method Swizzling

理解Method Swizzling是学习runtime机制的一个很好的机会。在此不多做整理,仅翻译由Mattt Thompson发表于nshipster的Method Swizzling一文。 ...

Objective-C Runtime 运行时之四:Method Swizzling

原文地址: http://blog.jobbole.com/79580/ 理解Method Swizzling是学习runtime机制的一个很好的机会。在此不多做整理,仅翻译由Mat...

Objective-C Runtime 运行时之:Method Swizzling

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

Objective-C Runtime 运行时之四:Method Swizzling

转自:http://southpeak.github.io/blog/2014/11/06/objective-c-runtime-yun-xing-shi-zhi-si-:method-swizzl...

Objective-C Runtime 运行时之四:Method Swizzling

在上周associated object一文中,我们开始探索Objective-C运行时的一些黑魔法。本周我们继续前行,来讨论可能是最受争议的运行时技术:method swizzling。   ...

Objective-C Runtime 运行时之四:Method Swizzling

在上周associated objects一文中,我们开始探索Objective-C运行时的一些黑魔法。本周我们继续前行,来讨论可能是最受争议的运行时技术:method swizzling。 ...

Objective-C Runtime 运行时之四:Method Swizzling

原文出处: 南峰子的技术博客 理解Method Swizzling是学习runtime机制的一个很好的机会。在此不多做整理,仅翻译由Mattt Thompson发表于nshipste...

Objective-C运行时特性:Method Swizzling魔法

OC运行时特性,为我们提供了一个叫做Method Swizzling的方法魔法利器,利用它我们可以更加随心所欲的在运行时期间对编译器已经的方法再次动手脚,主要包括:交换类中某两个方法的实现、重新添加或...

Objective-C的hook方案(一): Method Swizzling

在没有一个类的实现源码的情况下,想改变其中一个方法的实现,除了继承它重写、和借助类别重名方法暴力抢先之外,还有更加灵活的方法吗?在Objective-C编程中,如何实现hook呢?标题有点大,计划分几...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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