在Swift之前,在Objective-C中,我会在类中调用或挂钩方法
.
如果有人有任何关于修改Swift的运行时和挂钩函数的信息,比如CydiaSubstrate和其他帮助这个领域的库,请通知我.
一年多以后,我正在回答这个问题,因为其他答案都没有提供针对各类课程调整的明确要求.
什么是其他的描述,而它将完美的运作进行功能扩展到基础/ UIKit类(如NSDictionary中),只会永远不会为自己的雨燕类工作.
如上所述这里,有一个方法混写其他比你的自定义类扩展NSObject的一个额外的要求.
必须标记 您想要调配的快速方法dynamic
.
如果不对其进行标记,则运行时将继续调用原始方法而不是调整方法,即使方法指针看起来已正确交换.
我在博文中扩展了这个答案.
你很可能会在没有任何问题的情况下调用从Objective-C类继承的swift生成的类,因为它们似乎一直使用动态方法调度.您可以通过跨桥传递在Objective-C运行时中存在的快速定义的类的方法,但Objective-C方法可能只是通过桥接到swift的代理 - 边运行时,所以不清楚它们是否特别有助于调整它们.
"纯粹的"快速方法调用似乎不是通过任何类似的方式动态调度的objc_msgSend
,并且看起来(来自简短的实验)swift的类型安全性在编译时实现,并且大部分实际类型信息不存在(即消失)在运行时为非类型类型(这两种类型都可能有助于swift的速度优势.)
出于这些原因,我认为有意义的混合swift-only方法将比调整Objective-C方法更难,并且可能看起来mach_override
比Objective-C方法更加混乱.
我在Swift中使用方法调配成功了.此示例显示如何在NSDictionary上挂钩描述方法
我的实施:
extension NSDictionary { func myDescription() -> String!{ println("Description hooked") return "Hooooked " + myDescription(); } }
调色代码:
func swizzleEmAll() { var dict:NSDictionary = ["SuperSecret": kSecValueRef] var method: Method = class_getInstanceMethod(object_getClass(dict), Selector.convertFromStringLiteral("description")) println(dict.description) // Check original description var swizzledMethod: Method = class_getInstanceMethod(object_getClass(dict), Selector.convertFromStringLiteral("myDescription")) method_exchangeImplementations(method, swizzledMethod) println(dict.description) //Check that swizzling works }
编辑: 此代码适用于任何继承自NSObject的自定义Swift类(但不适用于不支持的类.)更多示例 - https://github.com/mbazaliy/MBSwizzler