例如,在以下代码行中:
DispatchQueue.global(qos: .userInitiated).async { ... }
为什么.userInitiated
以句点开头?这是源于目标C还是Swift特有的?
注意:TLDR版本位于底部
这称为隐式成员表达式。
隐式成员表达式
隐式成员表达式是在类型推断可以确定隐式类型的上下文中访问某个类型(如枚举事例或类型方法(的成员的缩写方式。
因此,只要Swift知道类型,你就可以经常省略键入,比如
let colour: UIColor = .red
它通常用于枚举值和静态类型,并可用于将参数传递给函数,如上面的DispatchQueue
示例。另一个简化的例子是:
enum Colors {
case yellow, blue, red, green
}
所以如果你有这个函数。。
func draw(withColor: Colors) {
}
您应该能够传入带有前缀.的枚举,就像一样
draw(withColor: .yellow)
这是一种更详细的快捷方式:
draw(withColor: Colors.yellow)
解决方案
具体地说,这里的.userInitiated
实际上是DispatchQoS上的一个静态属性,所以它只是键入DispatchQoS.userInitiated
的一种较短的方式。Swift允许您缩短它,因为它知道预期的类型是DispatchQoS
其他答案很好地描述了OP的情况。但"点语法"并不是Swift中的"仅枚举"功能,它是以更通用的方式实现的。
您可以访问返回具有"点语法"的类型实例的所有类型成员,其中可以推断类型。
所以,你可以写这样的东西:
Swift 3
class MyClass {
var value: Int
init(value: Int) {
self.value = value
}
static var `default` = MyClass(value: 0)
private static var cache: [Int: MyClass] = [:]
static func cachedInstance(value: Int) -> MyClass {
if let instance = cache[value] {
return instance
} else {
let instance = MyClass(value: value)
cache[value] = instance
return instance
}
}
}
var myObject: MyClass = .default //Accessing a type property
myObject = .cachedInstance(value: 2) //Accessing a type method
myObject = .init(value: 1) //Accessing an initializer
Swift 2
var myObject: MyClass = .`default` //Accessing a type property
myObject = .cachedInstance(2) //Accessing a type method
myObject = .init(value: 1) //Accessing an initializer
这实际上是一个枚举。枚举可以是多种情况之一。在您的示例中,案例是.userInitiated
,它是QOSClass.userInitiated
的缩写。这个案例确实代表了一些东西,它不一定有任何相关的价值。苹果公司的网站上有一个很棒的、实用的枚举示例:
enum CompassPoint {
case North
case South
case East
case West
}
通过在类型后面加一个点,然后加上成员名称来访问枚举成员,如下所示:CompassPoint.North
。但是,如果期望的类型在上下文中是明确的,那么您可以省略该类型,只使用.North
。
在您的示例中,枚举类型为QoSClass
。但是,由于DispatchQueue.global(qos:)
需要类型为QoSClass
的枚举,您可以省略该类型,只使用.userInitiated
,因为Swift可以从上下文推断该类型。
我说过枚举不一定要有关联的值,但它们可以。具有关联值的枚举可能非常强大,这是Swift中我最喜欢的部分之一。你可以在这里阅读更多关于这一切的信息:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Enumerations.html
您还可以在这里了解更多关于新GCD API如何实现的信息:https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md