Swift / Objective-C桥接中的循环引用

任何拥有两年以上历史的iOS / MacOS项目都必须处理Swift和Objective-C的混搭 ,在这种环境中,不同的语言会试图共存。

但是,这种和平可能会受到某些特殊条件的威胁,在某些特殊条件下,由于歧义性,无法正确建立两种语言之间的桥梁,例如在循环引用的情况下。

以这种情况为例:

  1. ObjcMainClass由符合Swift编写的ComponentProtocol的对象组成,因此需要导入ProjectName-Swift.h生成的文件
  2. ObjcMainClassTests是用于测试ObjcMainClass组件的Objective-C单元测试类。 它将使用符合ComponentProtocolStubComponent对象,以控制要测试的公共方法的执行流程。
  3. StubComponent是在单元测试目标中定义的,并且需要包含@testable import ProjectName代码才能找到协议定义。
  4. 由于StubComponent位于单元目标中,并且是用Swift编写的,因此ObjcMainClassTests必须导入ProjectNameTests-Swift.h生成的文件。

尝试运行单元测试,您得到的是“在ProjectNameTests-Swift.h中找不到模块ProjectName”错误:

在采用模拟单元测试方法的项目中,这种情况可能很常见,其中将新Swift接口的具体存根传递到现有的Objective-C实体。

最好的解决方案是减少Objective-C和Swift代码之间所需的桥梁数量。 尝试将模块或对象图迁移到Swift,或在计划迁移本身之前在Objective-C中临时编写协议和存根。

第二种方法显示在Github上的演示项目中,您可以在此处找到失败和通过的场景:https://github.com/matsoftware/TestObjcSwiftCircularReference。

桥接愉快☺