在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)
答案 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,例如contains
和intersect
以及isEmpty
。并且您可以使用set / array-style literal来构造值,这更准确地表示"我想要Hour
和Day
组件"而不是"我想要一些整数值,即Hour
和Day
是"的按位OR。