在 Apple 关于与 C API 交互的文档中,他们描述了将 NS_ENUM
标记的 C 样式枚举作为 Swift 枚举导入的方式。这是有道理的,因为 Swift 中的枚举很容易作为 enum
值类型提供,所以很容易看出如何创建我们自己的。
再往下,它说的是关于 NS_OPTIONS
标记的 C 样式选项:
Swift also imports options marked with the
NS_OPTIONS
macro. Whereas options behave similarly to imported enumerations, options can also support some bitwise operations, such as&
,|
, and~
. In Objective-C, you represent an empty option set with the constant zero (0
). In Swift, usenil
to represent the absence of any options.
鉴于 Swift 中没有 options
值类型,我们如何创建一个 C-Style options 变量来使用?
几乎与 Swift 2.0 相同。 OptionSetType 被重命名为 OptionSet 并且枚举按惯例写成小写。
struct MyOptions : OptionSet {
let rawValue: Int
static let firstOption = MyOptions(rawValue: 1 << 0)
static let secondOption = MyOptions(rawValue: 1 << 1)
static let thirdOption = MyOptions(rawValue: 1 << 2)
}
Swift 3 建议使用空数组文字,而不是提供 none
选项:
let noOptions: MyOptions = []
其他用法:
let singleOption = MyOptions.firstOption
let multipleOptions: MyOptions = [.firstOption, .secondOption]
if multipleOptions.contains(.secondOption) {
print("multipleOptions has SecondOption")
}
let allOptions = MyOptions(rawValue: 7)
if allOptions.contains(.thirdOption) {
print("allOptions has ThirdOption")
}
在 Swift 2.0 中,协议(protocol)扩展负责处理这些的大部分样板文件,这些样板文件现在作为符合 OptionSetType
的结构导入。 (从 Swift 2 beta 2 开始,RawOptionSetType
已经消失。)声明要简单得多:
struct MyOptions : OptionSetType {
let rawValue: Int
static let None = MyOptions(rawValue: 0)
static let FirstOption = MyOptions(rawValue: 1 << 0)
static let SecondOption = MyOptions(rawValue: 1 << 1)
static let ThirdOption = MyOptions(rawValue: 1 << 2)
}
现在我们可以通过 MyOptions
使用基于集合的语义:
let singleOption = MyOptions.FirstOption
let multipleOptions: MyOptions = [.FirstOption, .SecondOption]
if multipleOptions.contains(.SecondOption) {
print("multipleOptions has SecondOption")
}
let allOptions = MyOptions(rawValue: 7)
if allOptions.contains(.ThirdOption) {
print("allOptions has ThirdOption")
}
查看由 Swift 导入的 Objective-C 选项(例如 UIViewAutoresizing
),我们可以看到选项被声明为符合协议(protocol)的 struct
RawOptionSetType
,依次符合_RawOptionSetType
、Equatable
、RawRepresentable
、BitwiseOperationsType
、和 NilLiteralConvertible
。我们可以像这样创建自己的:
struct MyOptions : RawOptionSetType {
typealias RawValue = UInt
private var value: UInt = 0
init(_ value: UInt) { self.value = value }
init(rawValue value: UInt) { self.value = value }
init(nilLiteral: ()) { self.value = 0 }
static var allZeros: MyOptions { return self(0) }
static func fromMask(raw: UInt) -> MyOptions { return self(raw) }
var rawValue: UInt { return self.value }
static var None: MyOptions { return self(0) }
static var FirstOption: MyOptions { return self(1 << 0) }
static var SecondOption: MyOptions { return self(1 << 1) }
static var ThirdOption: MyOptions { return self(1 << 2) }
}
现在我们可以处理这个新的选项集 MyOptions
,就像 Apple 文档中描述的那样:您可以使用类似 enum
的语法:
let opt1 = MyOptions.FirstOption
let opt2: MyOptions = .SecondOption
let opt3 = MyOptions(4)
而且它的行为也像我们期望的选项一样:
let singleOption = MyOptions.FirstOption
let multipleOptions: MyOptions = singleOption | .SecondOption
if multipleOptions & .SecondOption != nil { // see note
println("multipleOptions has SecondOption")
}
let allOptions = MyOptions.fromMask(7) // aka .fromMask(0b111)
if allOptions & .ThirdOption != nil {
println("allOptions has ThirdOption")
}
我已经建立了一个 generator to create a Swift option set没有所有的查找/替换。
最新: Swift 1.1 beta 3 的修改。
关于ios - 如何在 Swift 中创建 NS_OPTIONS 样式的位掩码枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38833030/
欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://jike.in/) | Powered by Discuz! X3.4 |