在之前讲到基础类型桥接Swift的时候,我们提过会用一组有相同命名规则的变量表示某个范围里相关的值。实际上,我们也可能在C里用一个真正的enum来表达类似的概念:

// In traditional_oc.h

typedef enum {
    RED, YELLOW, GREEN
} TrafficLightColor;

对于这个定义,Swift会如何桥接呢?

不如我们所想的enum桥接

你可能想当然的觉得,直接桥接到Swift原生的enum不就好了。但实际上并不如此,C中的enum会被打散成一个同名的struct和由C中所有的enum成员命名的全局变量,就像这样:

/// struct TrafficLightColor: RawRepresentable, Equatable { }

/// var RED: TrafficLightColor { get }
/// var YELLOW: TrafficLightColor { get }
/// var GREEN: TrafficLightColor { get }

于是,在Swift里,我们要这样使用TrafficLightColor

let r = RED
print(r.rawValue) // 0

可以看到,生成的TrafficLightColor只有一个rawValue属性,它的值就是C中每一个enum成员的值。只是,这些全局变量都是只读的,我们不能修改他们。

当然,这和我们想象的一点儿也不一样。要让C中的enum直接映射到Swift原生的enum怎么办呢?我们可以借助一个宏。

使用NS_ENUM

traditional_oc.h中,把之前TrafficLightColor的声明改成这样:

typedef NS_ENUM(int, TrafficLightColor) {
    RED,
    YELLOW,
    GREEN
};

其中,NS_ENUM的第一个参数表示每一个enum case对应的值类型,第二个参数表示要桥接到Swift的类型名。这样,TrafficLightColor就会桥接成下面这样的Swift原生enum

enum TrafficLightColor: CInt {
    case RED,
    case YELLOW,
    case GREEN
}

我们可以用下面的代码观察这个结果:

let r: TrafficLightColor = .RED

print(type(of: r)) // TrafficLightColor
print(r.rawValue)  // 0
print(type(of: r.rawValue)) // Int32

注意这次,我们给r赋值的时候,使用了.RED

What's next?

至此,我们就掌握了C中的各种基本类型桥接到Swift的方式。如果你确认没问题,接下来,我们就要进入到C的腹地,了解Swift中的指针类型家族是如何与C的原生指针进行交互的。

所有订阅均支持 12 期免息分期

¥ 59

按月订阅

一个月,观看并下载所有视频内容。初来泊学,这可能是个最好的开始。

开始订阅

¥ 512

按年订阅

一年的时间,让我们一起疯狂地狩猎知识吧。比按月订阅优惠 28%

开始订阅

¥ 1280

泊学终身会员

永久观看和下载所有泊学网站视频,并赠送 100 元商店优惠券。

我要加入
如需帮助,欢迎通过以下方式联系我们