尝试理解NS_REFINED_FOR_SWIFT在整个类中使用时

xqk2d5yq  于 2023-08-02  发布在  Swift
关注(0)|答案(2)|浏览(115)

我正在做一个用Objective-C编写的框架项目。我试图确保最终的公共Swift API遵循现代标准。因此,我正在研究像NS_SWIFT_NAMENS_REFINED_FOR_SWIFT这样的宏。我看过苹果的Objective-C and C Code Customization文档。但是他们只有一个使用NS_REFINED_FOR_SWIFT的例子,而且是在方法级别。
我碰巧在看CloudKit框架中的一些Apple头文件,特别是新的CKSyncEngine相关类型。我注意到每个Objective-C类的前缀都是NS_REFINED_FOR_SWIFT。由于现在每个类名和方法名都用双下划线前缀隐藏,我想这意味着不仅仅是一个简单的Swift类扩展来帮助更好地Map方法和属性名。
我需要帮助的是一个开始的例子,当几个Objective-C类标记为NS_REFINED_FOR_SWIFT时。在框架中必须提供哪些Swift代码才能正确地公开这些细化的类名?
让我们从一个看起来很像UIButtonUIButton.Configuration的例子开始。Objective-C头文件可能看起来像这样:

NS_REFINED_FOR_SWIFT
@interface MyButtonConfiguration: NSObject

@end

NS_REFINED_FOR_SWIFT
@interface MyButton: UIControl

- (instancetype)initWithConfiguration:(MyButtonConfiguration *)configuration NS_SWIFT_NAME(init(configuration:));

@end

字符串
这是一个非常简单的例子作为起点。如果代码真的这么简单,我可以很容易地在类名上使用NS_SWIFT_NAME并完成。但我试图理解一个复杂得多的API的起点。
最后,我希望Swift API的类名为MyButtonMyButton.Configuration(类似于嵌套的作用域)。
如果我没有在整个类上使用NS_REFINED_FOR_SWIFT,而只是一些方法/属性,那么我会添加Swift代码,例如:

extension MyButton {
    func someRefinedAPI() {
        __someOriginalAPI()
    }
}


但是在类级别使用NS_REFINED_FOR_SWIFT意味着在Swift中MyButton被暴露为__MyButtonMyButtonConfiguration被暴露为__MyButtonConfiguration。我需要在框架中添加哪些Swift代码,才能将这些细化的名称公开为MyButtonMyButton.Configuration
我尝试了如下的方法:

typealias MyButton = __MyButton // This works
typealias MyButton.Configuration = __MyButtonConfiguration // Gives error at the period with: Expected '=' in type alias declaration


我本来打算用细化的方法和属性的类扩展来跟踪它们,但我不能越过类名的起点。
那么,当在类级别使用NS_REFINED_FOR_SWIFT时,如何将Objective-C类名转换成嵌套的Swift类型层次结构呢?
在我真实的的框架中,会有Objective-C类型需要成为Swift中的第三层嵌套类型。例如,考虑UIButtonConfigurationSizeUIButton.Configuration.SizeNS_SWIFT_NAME似乎不接受3个级别的名称。

lx0bsm1f

lx0bsm1f1#

NS_REFINED_FOR_SWIFT用于通过参数中的指针返回值的API方法。Refined API将返回元组中的值。
NS_REFINED_FOR_SWIFT不能创建嵌套类。
你仍然可以写:

extension MyButton {
    typealias Configuration = __MyButtonConfiguration
}

字符串

kmbjn2e3

kmbjn2e32#

随着@Cy-4AH向正确方向的推动,我也想出了如何获得第3级。
例如,如果我想在Swift中将Objective-C类MyButtonConfigurationSize公开为MyButton.Configuration.Size,那么在添加第一个扩展之后,我需要:

extension MyButton.Configuration {
    typealias Size = __MyButtonConfigurationSize
}

字符串
现在看起来很明显。

相关问题