Swift是否支持面向方面的编程?

时间:2014-06-10 08:43:39

标签: ios swift

我是一名试图学习面向方面编程的iOS开发人员,但是Swift支持面向方面的编程吗?

2 个答案:

答案 0 :(得分:41)

Aspect Oriented Programming的基础是拦截模式。我们从横切要求开始 - 需要在应用程序的许多部分中发生。然后使用 切入点表达式 ,通过识别应用此要求的所有位置对其进行模块化。这是通过拦截方法调用和编织其他行为来完成的。因此,对于支持AOP的语言,它必须支持拦截模式。

现在,根据语言,可以在编译时,运行时或两者中应用方法拦截。 Swift在这方面是一个有趣的案例,因为它支持以下几种方法调度:

  • 静态/ vtable,与C ++一样(更快:在测试中占用方法调用时间约1.1纳秒或更少)
  • Messaging,与Objective-C 一样(较慢:在测试中占据方法调用时间约4.9纳秒)。也称为 动态调度 后期绑定

如果你扩展NSObject或使用@objc装饰,那么将使用消息传递。否则Swift将恢复为static / vtable方法调用。

  • 使用static / vtable类型的分派,只能进行编译时拦截。在C ++(和Swift)的情况下,这涉及使用在实际编译之前生成新源的预处理器。这是一种有点麻烦的方法,需要花费更多精力来开发必要的工具。虽然它确实提供了最佳性能。
  • 使用方法调用的消息传递方式,也可以使用运行时拦截。事实上,Objective-C使截取变得如此简单,以至于没有正式的AOP框架。它可能是有用的,但“原材料”非常好,没有人费心去做一个。 Cooca的许多最佳功能都利用了Objective-C的动态调度和拦截方法调用的能力。

<强>要点:

  • 如果扩展NSObject或使用'@objc'装饰,Swift将支持运行时AOP。这有一些怪癖和限制 - 苹果公司关于在Swift中使用KVO的指南将指出其中大部分内容。
  • 如果你没有扩展Objective-C基础或使用'@objc'装饰,那么只能编译时AOP。目前还没有这样的库提供编译时AOP。此外,编译时AOP的一个缺点是它只适用于您拥有源的类。

NB1:某些语言(如Java)使用静态/ vtable样式的方法调度,仍然支持运行时方法拦截。这是可能的,因为它们依赖于虚拟机,以及 类加载器 ,这是另一个挂钩点。事实上,Java仍被归类为“后期绑定”语言。

NB2:它在技术上可以支持对编译到机器代码二进制文件进行编译时编织,但有一些限制。首先是没有太多工具可以支持这一点,因为实施工作量很大,必须在每个平台上重复。第二是它限制了可用的AOP功能。

答案 1 :(得分:6)

不幸的是,Swift本身目前没有运行时支持。你必须依赖Objective-C桥接。

这是一个全新的iOS AOP库,用Objective-C编写,支持Swift。

https://github.com/MO-AI/MOAspects

仅在咨询之前#39;和#39;建议&#39;是可用的,但在大多数情况下,它足以解决您的问题。 请注意,可能需要添加动态&#39;当对纯Swift类/方法的拦截不能正常工作时,你的函数的关键字。

MOAspects优于两个最着名的Objective-C,Aspects和BlockInjection的AOP库。 Aspects不支持类方法拦截和多个挂钩到类层次结构中的方法。 BlockInjection有一个关键问题,不支持64位。