我正在处理现有的大型代码库,该代码库主要是 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 代码后,@objc(XXClassA)
也可以从 Swift 类中删除。
不幸的是,如果您有一个 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,则初始化程序不可用。
如果我将 ClassA 重新定义为这个,一切都会好起来的。
class XXClassA: NSObject {
let foo = "bar"
}
我理解为什么会发生这种情况以及我已采取的修复措施,但是我想继续使用这种带有前缀的 ObjC 类模式。关于如何避免循环导入,同时又保持命名约定的任何想法?
这里有完整的代码示例:https://gist.github.com/justAnotherDev/78483f9d94e40fd90c38
最佳答案
我遇到了同样的问题。我的解决方法是:
- 为 Swift 类使用 objc 风格的前缀名称。
- 添加类型别名:
typealias ClassA = XXClassA
。 - 始终使用 Swift 代码中的无前缀名称。
使用此模式,至少可以在最后一个 objc 依赖项消失时轻松删除前缀。
关于objective-c - Swift/ObjC 循环导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35590015/