An optional chain is a process of ** querying and calling properties, methods, and subscripts ** on ** optional (possibly nil) sequences **. Calls to properties, methods, and subscripts will succeed if the optional variable contains a value, and calls to properties, methods, and subscripts will return nil if the optional variable is equal to nil. Multiple queries can be linked together, and if one of the calling nodes fails, the whole process will fail and return nil.

Optional chains in Swift are similar to nil in Objective-C, but can work for any type, not just object types, but value types as well.

Optional chain VS mandatory unpacking

Optional types can be used in two ways, using ‘? ‘Construct optional chain and use ‘! ‘to force unpack. Optional chain if failure (?) Returns nil in an elegant manner, forcing unpacking if optional (!) A runtime error is triggered.

By * * * * ‘? ‘Declare optional properties. Instead of providing defaults, the system provides nil defaults for all types

The return of an optional chain must be an optional value, and a property, method, or subscript that returns a non-optional value during a count call is automatically converted to an optional value.

The return of the optional chain must be nil or an optional value

Disadvantages of forced unpacking

class Person { var residence: Residence? }class Residence {var numberOfRooms = 1} let John = Person()Copy the code

John. residence == nil.

let roomCount = john.residence! .numberOfRooms // this triggers a runtime errorCopy the code

Using the ‘! ‘Force unpacking the optional variable residence, which triggers a runtime error.

If residence has a non-nil value, roomCount is assigned a simple value of non-optional type.

Optional chain advantage

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."Copy the code

Whether John. Residence? Was it successful, John. Residence? NumberOfRooms must return an optional value type, nil or Int? .

Properties are accessed via optional chains

let john = Person() 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."Copy the code

Call a method through an optional chain

class Residence { var rooms = [Room]() var numberOfRooms: Int { return rooms.count } subscript(i: Int) -> Room { get { return rooms[i] } set { rooms[i] = newValue } } func printNumberOfRooms() { print("The number of rooms is \(numberOfRooms)") } var address: Address? } if john.residence? .printNumberOfRooms() ! = nil { print("It was possible to print the number of rooms.") } else { print("It was not possible to print the number of rooms.") } // Prints "It was not possible to print the number of rooms."Copy the code

Subscripts are accessed via optional chains

if let firstRoomName = john.residence? [0].name { print("The first room name is \(firstRoomName).") } else { print("Unable to retrieve the first room name.") }  // Prints "Unable to retrieve the first room name."Copy the code

Access the subscripts of optional types

var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]] testScores["Dave"]? [0] = 91 testScores["Bev"]? [0] += 1 testScores["Brian"]? [0] = 72 // the "Dave" array is now [91, 82, 84] and the "Bev" array is now [80, 94, 81]Copy the code

Multiple optional chains return invariance

Multiple optional chains, whether successful or not, return the optional value corresponding to the last node on the sequence.

data

Docs.swift.org/swift-book/…