我正在开发一个主要是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,则初始化程序不可用。

objective-c - Swift/ObjC循环导入-LMLPHP

如果我改用ClassA来重新定义,一切都会好起来的。
class XXClassA: NSObject {
    let foo = "bar"
}

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

完整的代码示例在这里:https://gist.github.com/justAnotherDev/78483f9d94e40fd90c38

最佳答案

我有同样的问题。我的解决方法是:

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

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

    09-10 02:03
    查看更多