【发布时间】:2014-06-10 08:43:38
【问题描述】:
我是一名尝试学习面向方面编程的 iOS 开发人员,但 Swift 是否支持面向方面编程?
【问题讨论】:
我是一名尝试学习面向方面编程的 iOS 开发人员,但 Swift 是否支持面向方面编程?
【问题讨论】:
Aspect Oriented Programming 的基础是拦截模式。我们从一个横切需求开始——需要在应用程序的许多部分中出现的东西。然后使用 切入点表达式,通过识别所有应应用此要求的位置来对其进行模块化。这是通过拦截方法调用并编织其他行为来完成的。因此,对于支持 AOP 的语言,它必须支持拦截模式。
现在,根据语言的不同,可以在编译时、运行时或同时应用方法拦截。 Swift 在这方面是一个有趣的案例,因为它支持以下几种方法调度:
如果您扩展 NSObject 或使用 @objc 装饰,则将使用消息传递。否则 Swift 将恢复为静态/vtable 方法调用。
总结:
NB1: 一些语言,例如 Java,使用静态/vtable 风格的方法分派,并且仍然支持运行时方法拦截。这是可能的,因为它们依赖于虚拟机以及另一个连接点 类加载器。事实上,由于这个原因,Java 仍然被归类为“后期绑定”语言。
NB2:它在技术上可以支持针对已编译到机器代码的二进制文件提供编译时编织,但有一些限制。首先是没有太多工具来支持这一点,因为实施工作量很大,并且必须在每个平台上重复。第二个是它限制了可用的 AOP 功能。
【讨论】:
不幸的是,Swift 本身目前还没有运行时支持。您必须依赖 Objective-C 桥接。
这是一个全新的 iOS AOP 库,用 Objective-C 编写,支持 Swift。
https://github.com/MO-AI/MOAspects
只有 'before advice' 和 'after advice' 可用,但在大多数情况下,足以解决您的问题。 请注意,当对纯 Swift 类/方法的拦截无法正常工作时,可能需要向您的函数添加“动态”关键字。
MOAspects 优于 Objective-C 的两个最著名的 AOP 库,Aspects 和 BlockInjection。 Aspects 不支持类方法拦截和多个挂钩到类层次结构中的方法。 BlockInjection 有一个关键问题是不支持 64 位。
【讨论】: