有没有办法在 Objective-C 中使用 Swift 结构而不使它们成为类?



我在.swift文件中用 swift 编写了几个简单的structs。 这些structs非常简单,几乎只包含字符串:

struct Letter {
struct A {
static let aSome : String = "descASome"
static let aSomeMore : String = "descASomeMore"
}
struct B {
static let bNow : String = "descBNow"
static let bLater : String = "descBLater"
}
...
}

我想在包含Objective-C代码的项目中使用这些结构,因为我正在编写一个跨平台框架。

我读过:ObjectiveC - Apple 的 Swift 互操作性,其中明确指出 Swift 编写的结构不能被 ObjectiveC 使用。 不包括(除其他功能外(:

在 Swift 中定义的结构

解决方案 1:

我找到了一个通过使用类解决问题的 SO 解决方案:

@objc class Letter : NSObject {
@objc class A : NSObject {
static let aSome : String = "descASome"
static let aSomeMore : String = "descASomeMore"
}
@objc class B : NSObject {
static let bNow : String = "descBNow"
static let bLater : String = "descBLater"
}
...
}

这个解决方案有效,但是我必须将所有结构重写为类。它们也不像结构(除其他外(那样轻量级。 此外,我觉得我正在倒退解决问题。

问题 1.除了解决方案 1 之外,还有其他方法可以在 ObjectiveC 中使用不适合我的项目/情况的 Swift 结构吗?(如果枚举的原始值为 Int,则可以使用枚举(

问题 2.有没有办法使用 #define SomeConst 进行 ObjectiveC 访问和 Swift 访问,例如:

#if macOS // if Swift?
#endif

截至目前,没有。 您将需要类来存储模型对象。

@objcMembers public class Car: NSObject {
public var mileage: NSNumber?
}

@objcMember虚拟地将它们转换为Objective-c可读格式,并且可以从Objective-C类访问。 这将使您的代码可互操作。

注意:确保类类型为NSObject

如果不进行一些重写,就无法做到这一点:Swift 结构在 ObjC 中根本看不到。

你需要编写一个 ObjC 可见的 Swift 类来公开这些值,有点像 Swift Foundation 的"覆盖"类型的反面。

一种选择是尽可能严格地遵循 Swift 代码的结构。请注意,嵌套类是不允许的,并且 ObjC "overlay" 必须具有与 Swift 结构不同的名称。这是不幸的,但无法解决,因为此 Swift 代码在与原始结构相同的位置可见。

import Foundation
@objc class OCLetters : NSObject {
static let A = _A.self
static let B = _B.self
}
@objc class _A : NSObject {
static let some = Letters.A.some
static let someMore = Letters.A.someMore
}
@objc class _B : NSObject {
static let now = Letters.B.now
static let later = Letters.B.later
}

但是,如果要对 ObjC 代码中的值使用点表示法,这将不起作用。这可能是一个错误,但OCLetters.A.some中的.some被视为结构成员引用,这将失败。(将属性更改为计算类属性也不起作用。您必须写[[OCLetters A] some](或[OCLetters.A some](。

为了能够使用点表示法,您必须稍微更改结构,以便属性实际上是实例:

import Foundation
@objc class OCLetters : NSObject {
static let A = _A()
static let B = _B()
}
@objc class _A : NSObject {
let some = Letters.A.some
let someMore = Letters.A.someMore
}
@objc class _B : NSObject {
let now = Letters.B.now
let later = Letters.B.later
}

另请注意,不幸的是,您无法限制帮助程序_A_B类在 ObjC 中的可见性,因为如果它们不可见,OCLetters的属性也不会可见。

相关内容

最新更新