This is the 18th day of my participation in Gwen Challenge

Optional chain call

  • Optional chain call: the current value may benilIs used to obtain its properties, methods and subscripts. If the optional value has a value, the call succeeds, if the optional value isnil, the call will returnnil
  • Multiple calls can be joined together to form a call chain if any of the nodes isnil, the entire call chain will fail, that is, returnnil

Use optional chain calls instead of forced unpacking

class Student {
    var hobby: Hobby?
}
class Hobby {
    var run = "run"
}

// Creates a new Student instance whose Hobby property is initialized to nil because it is selectable
let stu = Student()

// If an exclamation point '! 'Forcing expansion to obtain the run value in the STu's Hobby property triggers a runtime error because run has no value to expand
lethobby = stu.hobby! .run// Runtime error

// Stu. hobby is non-nil, the above call succeeds and sets run to String
lethobby = stu.hobby? . run/ / without error
Copy the code

Define the model for optional chain calls

Use a simple model to illustrate the use of optional chains (optional chain calls access properties, optional chain calls call methods, optional chain calls access subscripts, and so on)

class Person {
    var residence: Residence?
}

class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        get {
            return rooms[i]
        }
        set {
            rooms[i] = newValue
        }
    }

    // This method does not specify a return type. Functions and methods that do not have a return type have an implicit return type Void. The return value can be () or an empty tuple.
    func printNumberOfRooms() {
        print("The number of rooms is \(numberOfRooms)")}var address: Address?
}

class Room {
    let name: String
    init(name: String) { self.name = name }
}

class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        ifbuildingName ! = nil {return buildingName
        } else ifbuildingNumber ! = nil && street ! = nil {return "\(buildingNumber) \(street)"
        } else {
            return nil
        }
    }
}
Copy the code
Access properties via optional chain
  • Reads the properties

    Since John. residence is nil, this optional chain call will fail

    let john = Person()
    if letroomCount = john.residence? .numberOfRooms { print("John's residence has \(roomCount) room(s).")}else {
        print("Unable to retrieve the number of rooms.")}//Unable to retrieve the number of rooms.
    Copy the code
  • Set properties

    Setting the address property with John. residence will also fail because John. residence is currently nil

    let someAddress = Address()
    someAddress.buildingNumber = "29"
    someAddress.street = "Acacia Road"john.residence? .address = someAddressCopy the code
Call a method via an optional chain
  • You can call a method via an optional chain and determine if the call succeeded, even if the method returns no value
  • If the method is called on an optional value via an optional chain, the return type of the method will beVoid?Rather thanVoidBecause the return value from the optional chain call is optional
    let john = Person()
    ifjohn.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.")}//It was not possible to print the number of rooms.
    Copy the code
Access subscripts via optional chain
  • With optional chain calls, you can access the subscript on an optional value and determine whether the subscript call was successful

    Note: When accessing the subscript of an optional value through an optional chain call, place the question mark before the square brackets instead of after the subscript. The question mark of an optional chain call generally follows the optional expression directly

  • Access the name of the first room in the rooms array of the residence instance stored by the John. residence property with subscript, because John. residence is nil, the subscript call fails

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

Connect multiple layers of optional chain calls

  • If the value you access is not optional, the optional chain call will return the optional value (eg: the optional chain call accesses oneIntValue will be returnedInt?)
  • If the value you are accessing is optional, the optional chained call does not make the optional return value “more optional” (optional chained call access)Int?Value will still be returnedInt?Value is not returnedInt??)