Swift 和比较 C typedef 枚举 [英] Swift and comparing C typedef enums
问题描述
我最近更新到 Xcode-Beta4.我正在使用 c api,并且有一个像这样的 typedef 枚举:
I recently updated to Xcode-Beta4. I'm working with a c api and there is a typedef enum like this:
typedef enum {
XML_ELEMENT_NODE= 1,
XML_ATTRIBUTE_NODE= 2,
...
} xmlElementType;
现在我有一个 xml 节点,我想检查它的类型.因此,正确的方法是:
Now I have a xml node, which type I want to check. Therefore the right way would be:
if currentNode.memory.type != XML_ELEMENT_NODE {
在 Beta 3 中,我不得不将 XML_ELEMENT_NODE
替换为 1
.现在这不起作用 anmyore.在这两种情况下,我都收到错误 xmlElementType is not convertible to UInt8
In Beta 3 I had to replace XML_ELEMENT_NODE
with 1
. Now this does not work anmyore. In both cases I get the error xmlElementType is not convertible to UInt8
推荐答案
最简单的解决方法是找到标题并将 typedef enum
替换为 typedef NS_ENUM(...)代码>.此解决方案的问题在于您团队中的每个人都必须做出更改.
The simplest workaround is to find the header and replace the typedef enum
with an typedef NS_ENUM(...)
. The problem with this solution is that everybody in your team has to make the changes.
问题是由 C 枚举转换为不透明类型(结构?)C.xmlElementType
引起的.这种类型有一个 UInt32
类型的单个属性 value
.不幸的是,此属性不公开.您可以从调试器中调用它,但在编译后的代码中使用它会导致错误.
The problem is caused by the fact that the C enum is converted into an opaque type (struct?) C.xmlElementType
. This type has one single property value
of type UInt32
. Unfortunately, this property is not public. You can call it from the debugger but using it in compiled code results in an error.
我设法使用 reflect
做了一个解决方法,但这是一个很大的问题:
I managed to do a workaround using reflect
but it's a big hack:
extension xmlElementType : Equatable {
}
public func ==(lhs: xmlElementType, rhs: xmlElementType) -> Bool {
var intValue1 = reflect(lhs)[0].1.value as UInt32
var intValue2 = reflect(rhs)[0].1.value as UInt32
return (intValue1 == intValue2)
}
var elementType = currentNode.memory.type
if elementType == xmlElementType(1) {
println("Test")
}
我认为这是一个错误.要么定义等式,要么以某种方式将结构转换为整数.
I think this is a bug. Either the equality should be defined or some way to cast the struct to an integer.
另一种选择是在桥接头中添加一个 inline
转换函数:
Another option is to add an inline
conversion function to your bridging header:
static inline UInt32 xmlElementTypeToInt(xmlElementType type) {
return (UInt32) type;
}
然后定义相等为
public func ==(lhs: xmlElementType, rhs: xmlElementType) -> Bool {
return ((xmlElementTypeToInt(lhs) == xmlElementTypeToInt(rhs))
}
然而,我发现的最简单的选择是将结构体强制转换为 UInt32
:
However, the most simple option I have found is to brutally cast the struct to an UInt32
:
public func ==(lhs: xmlElementType, rhs: xmlElementType) -> Bool {
var leftValue: UInt32 = reinterpretCast(lhs)
var rightValue: UInt32 = reinterpretCast(rhs)
return (leftValue == rightValue)
}
请注意,这不太可靠,因为您必须确保结构实际上有 32 个字节,并且它不是一个 UInt8
,例如.C 转换函数更稳定.
Note this is less reliable because you have to make sure that the struct actually has 32 bytes and it is not an UInt8
, for example. The C conversion function is more stable.
这篇关于Swift 和比较 C typedef 枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!