Swift 和比较 C typedef 枚举 [英] Swift and comparing C typedef enums

查看:24
本文介绍了Swift 和比较 C typedef 枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近更新到 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆