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

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

面向方面编程的基础是截取模式。 我们从一个横切的需求开始,这个需求在应用程序的很多部分都需要发生。 然后使用切入点expression式 ,模块化它,通过识别所有这些要求应用的地方。 这是通过拦截方法调用和编织另外的行为来完成的。 因此,对于支持AOP的语言,它必须支持拦截模式。

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

  • 静态/虚表,就像C ++一样 (更快:在testing中约占方法调用时间的1.1纳秒或更less)
  • 消息 ,像Objective-C (较慢:在testing中占用方法调用时间大约4.9纳秒)。 也称为dynamic调度后期绑定

如果扩展NSObject或使用@objc装饰,则将使用消息传递。 否则,Swift将恢复到静态/虚表forms的方法调用。

  • 使用静态/虚表types的调度,只有编译时拦截是可能的。 在C ++(和Swift)的情况下,这涉及到在实际编译之前使用一个生成新源的预处理器。 这是一个有点繁琐的方法,需要更多的努力来开发必要的工具。 尽pipe它确实提供了最好的性能。
  • 通过方法调用的消息传递风格,运行时拦截也是可用的。 实际上,Objective-C的拦截非常简单,没有正式的AOP框架。 这可能是有用的,但“原料”是如此之好,没有人打扰做一个。 Cooca的许多最好的特性利用了Objective-C的dynamic调度和拦截方法调用的能力。

概要:

  • 如果扩展NSObject或使用'@objc'装饰,Swift将支持运行时AOP。 这有一些怪癖和局限 – 苹果公司的Swift使用KVO的指南将指出其中大部分。
  • 如果你不扩展一个Objective-C库或者使用'@objc'装饰,那么只有编译时AOP才是可能的。 至今还没有这样的库来提供编译时AOP。 此外,编译时AOP的一个缺点是它只能用于你有源的类。

NB1:有些语言,比如Java,使用static / vtable风格的方法调度,仍支持运行时方法拦截。 这是可能的,因为他们依靠虚拟机,以及一个类加载器 ,另一个接入点。 事实上,Java仍然被归类为“后期绑定”语言。

NB2:在技术上可能支持提供编译时间与编译到机器代码二进制文件编织有一些限制。 首先是没有太多的工具来支持这个,因为实施的努力是高的,必须重复每个平台。 其次是它限制了可用的AOPfunction。

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

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

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

只有“build议之前”和“build议之后”可用,但在大多数情况下,解决问题就足够了。 请注意,当对纯Swift类/方法的拦截无法正常工作时,可能需要向函数中添加“dynamic”关键字。

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