Swift / ObjC循环导入

时间:2016-02-23 23:05:13

标签: objective-c swift interop

我正在开发一个主要是Objective-C的现有大型代码库,但正在转换为Swift。

新的类正在Swift中实现,但是其中一些类需要从现有的ObjC代码中访问。为了遵循ObjC和Swift最佳实践,新类没有前缀,但是使用ObjC的前缀定义。

/**
 Create contrived class that is named XXClassA in ObjC and ClassA in Swift.
 */
@objc(XXClassA) class ClassA: NSObject {
    let foo = "bar"
}

到目前为止,这一直很好; Swift代码使用ClassA(),ObjC使用[[XXClassA alloc] init]。删除所有引用XXClassA的ObjC代码后,也可以从Swift类中删除@objc(XXClassA)

不幸的是,如果您有一个ObjC类引用XXClassA然后Swift代码尝试在ClassA中使用该新类,则会发生故障。

假设我创建一个名为XXClassC的ObjC类,并使用XXClassA(实际上是Swift类ClassA)实例化自己

//
//  XXClassC.h
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@class XXClassA;

@interface XXClassC : NSObject

-(instancetype)initWithA:(XXClassA *)classA;

@end

NS_ASSUME_NONNULL_END

循环参考现已到位。如果我尝试从ClassA内部使用XXClassC,则初始化程序不可用。

enter image description here

如果我重新定义ClassA,那么一切都很好。

class XXClassA: NSObject {
    let foo = "bar"
}

我理解为什么会发生这种情况并且我已经有了解决方案,但是我想继续使用这种带前缀的ObjC类模式。关于如何避免循环导入的任何想法,还要保留命名约定?

此处的完整代码示例:https://gist.github.com/justAnotherDev/78483f9d94e40fd90c38

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。我的解决方法是:

  • 为Swift类使用objc样式的前缀名称。
  • 添加一个类型:typealias ClassA = XXClassA
  • 始终使用Swift代码中未加前缀的名称。

使用这种模式,当最后一个objc依赖关系消失时,至少很容易删除前缀。