我有几个简单的structs
用swift里面的.swift文件编写。
这些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 - Swift interoperability by Apple明确指出,ObjectiveC不能使用Swift编写的结构。 不包括(以及其他功能):
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"
}
...
}
此解决方案有效,但我必须将所有结构重写为类。它们也不像结构(以及其他东西)那样轻量级。 此外,我觉得我倒退去解决问题。
Q1。在解决方案1旁边的ObjectiveC中是否还有其他方法可以使用Swift结构,这不适合我的项目/情况? (如果rawValue为Int,则可以使用枚举)
Q2。有没有办法使用#define SomeConst进行ObjectiveC访问,并使用Stift进行Swift访问:
#if macOS // if Swift?
#endif
答案 0 :(得分:1)
如果不进行重写,你就无法做到这一点:从ObjC看不到Swift结构。
您需要编写一个ObjC可见的Swift类来公开值,这是Swift Foundation的“叠加”类型的反转。
一种选择是尽可能地遵循Swift代码的结构。请注意,不允许使用嵌套类,并且ObjC“overlay”必须具有与Swift结构不同的名称。这是不幸的,但不可能解决,因为这个Swift代码在原始结构所在的相同位置是可见的。
导入基金会
@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代码中的值使用点表示法,则不起作用。这可能是一个错误,但.some
中的OCLetters.A.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
的属性也不会
答案 1 :(得分:1)
截至目前,没有。 您将需要使用类来存储模型对象。
@objcMembers public class Car: NSObject {
public var mileage: NSNumber?
}
@objcMember 实际上将它们转换为Objective-c可读格式,并且可以从Objective-C类进行访问。 这将使您的代码具有互操作性。
注意:确保类类型为 NSObject 。