选项枚举等效于Swift

时间:2016-03-18 03:30:02

标签: objective-c swift

NSCalander类中采用这两种方法:

component(unit: NSCalanderUnit, fromDate: NSDate) -> Int
components(unitFlags: NSCalanderUnit, fromDate: NSDate) -> NSDateComponents

在第一种方法中,我们使用单个 NSCalanderUnit 调用它:

someCalander.component(unit: .Minute, fromDate: NSDate())

在第二种方法中,类型签名表明我们给它一个 NSCalanderUnit 但实际上提供了多个单元,我们需要像这样调用方法:

components(unitFlags: [.Hour, .Day], fromDate: NSDate)

现在,我理解为什么它只需要一个 NSCalanderUnit 而不是 [NSCalanderUnit] ,因为cocoa框架是用Objective-C编写的将代码桥接到swift。在Objective-C中,NSCalanderUnit是一个NS_Option“枚举”。我们使用位掩码来组合多个标志(或“选项”),我们使用按位运算符 |

所以我的问题:

为什么我们在方括号中调用它而不是像这样调用它:

components(unitFlags: .Hour | .Day, fromDate: NSDate)

3 个答案:

答案 0 :(得分:2)

这称为选项集,从Objective C NS_OPTION自动桥接。它们实际上是一种更加类型安全的处理枚举类型的方法,其中可以选择多个选项。在Swift中,这些值不会被视为位掩码(如在Objective C中,因此|运算符在此处无效),而是作为枚举的不同值。有效的选项集就像一个枚举集,提供了具有同等功能的类型安全桥。

Apple在此处指定其实施细节: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html

答案 1 :(得分:1)

  

为什么我们在它被认为是数组

时用数组文字调用它

它不是一个数组。它更像是一套。事实上,它是一个选项集。

答案 2 :(得分:1)

这是OptionSetType。它是您从C导入NS _ OPTIONS枚举时获得的内容,您可以使用链接文档页面上显示的样式在Swift中创建自己的内容:

struct PackagingOptions : OptionSetType {
    let rawValue: Int
    init(rawValue: Int) { self.rawValue = rawValue }

    static let Box = PackagingOptions(rawValue: 1)
    static let Carton = PackagingOptions(rawValue: 2)
    static let Bag = PackagingOptions(rawValue: 4)
    static let Satchel = PackagingOptions(rawValue: 8)
    static let BoxOrBag: PackagingOptions = [Box, Bag]
    static let BoxOrCartonOrBag: PackagingOptions = [Box, Carton, Bag]
}

为什么会这样?类似这样的类型,因为它们在API中使用,在概念上是:一个或多个唯一值的分组。我们在C中将它们创建为位域只是一个实现细节。除了最基本的集合结构和查询之外,对所有操作进行按位操作很容易出错,即使它是正确的,它也很冗长,并且没有清楚地阅读 - 一个人必须直觉一堆OR和AND表示"如果它是值A,B或D中的任何一个但不是C或E"。

相比之下,当您创建或导入OptionSetType时,您会自动实施all the set operations,例如containsintersect以及isEmpty。并且您可以使用set / array-style literal来构造值,这更准确地表示"我想要HourDay组件"而不是"我想要一些整数值,即HourDay是"的按位OR。