For example, in the following line of code:
DispatchQueue.global(qos: .userInitiated).async { ... }
Why does .userInitiated
start with a period? Does this follow from Objective C or is it specific to Swift?
Note: TLDR version at bottom
This is called Implicit member expression.
Implicit Member Expression
An implicit member expression is an abbreviated way to access a member of a type, such as an enumeration case or a type method, in a context where type inference can determine the implied type.
So as long as Swift knows the type you can often omit typing it, such as
let colour: UIColor = .red
It is often used for enum values and static types and can be used to pass in parameters to functions like your DispatchQueue
example above. Another simplified example would be:
enum Colors {
case yellow, blue, red, green
}
So if you had this function..
func draw(withColor: Colors) {
}
you should be able to pass in the enum with the .prefix, like so
draw(withColor: .yellow)
The more verbose way in which this is a shortcut to would be:
draw(withColor: Colors.yellow)
Solution
To answer your question specifically, the .userInitiated
here is actually a static property on DispatchQoS so its just a shorter way of typing DispatchQoS.userInitiated
. Swift lets you shorten it becase it knows the type that is expected is of type DispatchQoS
Other answers are describing the OP's case very well. But "dot syntax" is not an "enum only" feature in Swift, which is implemented in a more general way.
You can access all type members returning an instance of the type with "dot syntax" where the type can be inferred.
So, you can write something like this:
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
That is actually an Enumeration. Enumerations can be one of multiple cases. In your example, the case is .userInitiated
, which is short for QOSClass.userInitiated
. The case just really stands for something, it doesn't have to have any assosiated value. Apple has this great, practical example of an enum on their site:
enum CompassPoint {
case North
case South
case East
case West
}
You access an enums members by putting a dot after the type, followed by the member name, like this: CompassPoint.North
. But if the expected type is clear from context, then you can leave off the type, and just use .North
.
In your example, the enum type is QoSClass
. But because DispatchQueue.global(qos:)
expects an enum of type QoSClass
, you can leave off the type and just use .userInitiated
because Swift can infer the type from context.
I said enums don't have to have an associated value, but they can. Enums with associated values can be VERY powerful, and it's one of my favorite parts of Swift. You can read much more about all of this here: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Enumerations.html
You can also see more about how the new GCD API is implemented here: https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With