Optional Chaining
Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.
Optional Chaining as an Alternative to Forced Unwrapping
A property that normally returns an Int will return an Int? when accessed through optional chaining.
1 | class Person { |
Defining Model Classes for Optional Chaining
1 | class Person { |
Accessing Properties Through Optional Chaining
the attempt to set the address property of john.residence will fail, because john.residence is currently nil.
1 | let john = Person() |
The function prints “Function was called” before returning a value, which lets you see whether the right hand side of the = operator was evaluated.
1 | func createAddress() -> Address { |
Calling Methods Through Optional Chaining
functions and methods with no return type have an implicit return type of Void
1 | func printNumberOfRooms() { |
- If you call this method on an optional value with optional chaining, the method’s return type will be
Void?, notVoid, because return values are always of an optional type when called through optional chaining - Compare the return value from the printNumberOfRooms call against nil to see if the method call was successful
1 | if john.residence?.printNumberOfRooms() != nil { |
Any attempt to set a property through optional chaining returns a value of type Void?, which enables you to compare against nil to see if the property was set successfully
1 | if (john.residence?.address = someAddress) != nil { |
Accessing Subscripts Through Optional Chaining
The optional chaining question mark always follows immediately after the part of the expression that is optional
1 | if let firstRoomName = john.residence?[0].name { |
Similarly, you can try to set a new value through a subscript with optional chaining:
1 | john.residence?[0] = Room(name: "Bathroom") |
Now , it is ok
1 | let johnsHouse = Residence() |
Accessing Subscripts of Optional Type
1 | var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]] |
Linking Multiple Levels of Chaining
- If you try to retrieve an Int value through optional chaining, an Int? is always returned, no matter how many levels of chaining are used.
- Similarly, if you try to retrieve an Int? value through optional chaining, an Int? is always returned, no matter how many levels of chaining are used.
1 | if let johnsStreet = john.residence?.address?.street { |
Now, it is ok
1 | let johnsAddress = Address() |
Chaining on Methods with Optional Return Values
1 | if let buildingIdentifier = john.residence?.address?.buildingIdentifier() { |
the optional value you are chaining on is the buildingIdentifier() method’s return value, and not the buildingIdentifier() method itself.
1 | if let beginsWithThe = |