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

use*_*405 16 ios swift

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

Jas*_*ues 41

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

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

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

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

  • 使用static/vtable类型的dispatch,只能进行编译时拦截.在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功能.


小智 6

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

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

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

只有"建议之前"和"建议后"可用,但在大多数情况下,它足以解决您的问题.请注意,当对纯Swift类/方法的拦截无法正常工作时,可能需要向函数添加"dynamic"关键字.

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