The terminology used for these marks is Optional Chaining
. They are generally used for distinguishing the cases, for example, whether a property
is, a method call
returns nil
.
An example explained in Apple's language guide for Optional Chaining
is a good one to show the purpose of their use:
First, two classes called Person
and Residence
are defined:
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
} Residence instances have a single `Int` property called `numberOfRooms`, with a default value of **1**. `Person` instances
have an optional residence
property of type Residence
?.
If you create a new Person
instance, its residence
property is
default initialized to nil
, by virtue of being optional. In the code
below, john
has a residence
property value of nil
:
let john = Person()
If you try to access the numberOfRooms
property of this person’s
residence
, by placing an exclamation mark after residence
to
force the unwrapping of its value, you trigger a runtime error,
because there is no residence
value to unwrap:
let roomCount = john.residence!.numberOfRooms
// this triggers a runtime error
The code above succeeds when john.residence
has a non-nil value
and will set roomCount
to an Int
value containing the appropriate
number of rooms. However, this code always triggers a runtime
error when residence
is nil
, as illustrated above.
Optional chaining provides an alternative way to access the value of
numberOfRooms
. To use optional chaining, use a question mark in
place of the exclamation mark:
if let roomCount = john.residence?.numberOfRooms {
print("John's residence has \(roomCount) room(s).")
} else {
print("Unable to retrieve the number of rooms.")
}
// Prints "Unable to retrieve the number of rooms."
This tells Swift to “chain” on the optional residence
property
and to retrieve the value of numberOfRooms
if residence
exists.
Because the attempt to access numberOfRooms
has the potential to
fail, the optional chaining attempt returns a value of type Int?
, or
“optional Int”. When residence
is nil
, as in the example
above, this optional Int
will also be nil
, to reflect the fact
that it was not possible to access numberOfRooms
. The optional Int
is accessed through optional binding to unwrap the integer and assign
the nonoptional value to the roomCount
variable.
Note that this is true even though numberOfRooms
is a nonoptional
Int
. The fact that it is queried through an optional chain means
that the call to numberOfRooms
will always return an Int?
instead
of an Int
.
You can assign a Residence
instance to john.residence
, so that it
no longer has a nil
value:
john.residence = Residence()
Besides the general overview of Optional Chaining above, you can look at this answer in StackOverflow.
Hope this gives you some perspective on Optional Chaining.