能否用NS_SWIFT_NAME或NS_REFINED_FOR_SWIFT将C枚举全局函数转为Swift属性?
将C枚举映射函数转为Swift属性的可行方案
可以实现,下面提供两种正确的解决方法,并纠正你之前尝试中的问题:
方案一:修正NS_SWIFT_NAME的用法
NS_SWIFT_NAME不能直接指定属性名,需要先将全局函数映射为Swift中枚举的实例方法,再通过扩展封装成计算属性。
- 修改C头文件中的函数声明:
FOUNDATION_EXPORT NSString *myEnumString(MyEnum val) NS_SWIFT_NAME(MyEnum.stringValue(self:));
这里MyEnum.stringValue(self:)表示将该全局函数映射为MyEnum的实例方法stringValue()。
- 在Swift中扩展枚举,将方法转为计算属性:
extension MyEnum { var stringVal: String { return stringValue() } }
之后就可以直接通过枚举值调用属性:MyEnum.case1.stringVal。
方案二:正确使用NS_REFINED_FOR_SWIFT
使用NS_REFINED_FOR_SWIFT时,C函数在Swift中会被添加单下划线前缀(而非你写的双下划线),修正后即可正常调用。
- C头文件中的声明保持:
FOUNDATION_EXPORT NSString *myEnumString(MyEnum val) NS_REFINED_FOR_SWIFT;
- 修改Swift扩展中的函数调用:
extension MyEnum { var stringVal: String { return _myEnumString(self) as String } }
这里_myEnumString是Swift对该C函数的暴露名称,调用后桥接为String类型即可。
你之前尝试的错误说明
- 第一种尝试:
NS_SWIFT_NAME(MyEnum.stringVal)不符合语法要求,NS_SWIFT_NAME的参数必须是Swift函数名,不能直接指定属性名,因此编译器报错且无法识别。 - 第二种尝试:
NS_REFINED_FOR_SWIFT只会给函数名添加单下划线前缀,你写的__myEnumString是错误的名称,导致找不到函数。
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

