Bird
Raised Fist0
Swiftprogramming~5 mins

Optional chaining with ?. in Swift

Choose your learning style10 modes available
Introduction

Optional chaining lets you safely access properties or call methods on values that might be nil (empty). It helps avoid crashes by stopping if something is nil.

When you want to get a property from an object that might be nil.
When calling a method on an optional object without crashing if it's nil.
When accessing nested properties where any level might be nil.
When you want to write clean code without many if-let checks.
When you want to safely call a function on an optional value.
Syntax
Swift
class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()
let roomCount = john.residence?.numberOfRooms

The ? after residence means: if residence is nil, stop and return nil instead of crashing.

Optional chaining returns an optional value, so roomCount is an Int? (optional Int).

Examples
Here, residence is nil, so optional chaining stops and roomCount is nil.
Swift
class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()

// residence is nil, so this returns nil
let roomCount = john.residence?.numberOfRooms
print(roomCount)  // prints nil
Now residence exists, so optional chaining accesses numberOfRooms and returns it wrapped in Optional.
Swift
class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()
john.residence = Residence()

// residence is not nil, so this returns 1
let roomCount = john.residence?.numberOfRooms
print(roomCount)  // prints Optional(1)
Optional chaining can also call methods safely on optionals.
Swift
class Person {
    var residence: Residence?
}

class Residence {
    var rooms: [String] = []
    func printNumberOfRooms() {
        print("Number of rooms: \(rooms.count)")
    }
}

let john = Person()
john.residence = Residence()

// Call method safely with optional chaining
john.residence?.printNumberOfRooms()  // prints "Number of rooms: 0"
If the optional is nil, method calls via optional chaining do nothing.
Swift
class Person {
    var residence: Residence?
}

class Residence {
    var rooms: [String] = []
    func addRoom(name: String) {
        rooms.append(name)
    }
}

let john = Person()

// This does nothing because residence is nil
john.residence?.addRoom(name: "Living Room")

// residence is still nil
print(john.residence?.rooms.count)  // prints nil
Sample Program

This program shows optional chaining stopping safely when residence is nil, then working after residence is set.

Swift
class Person {
    var residence: Residence?
}

class Residence {
    var rooms: [String] = []
    func addRoom(name: String) {
        rooms.append(name)
    }
    func printNumberOfRooms() {
        print("Number of rooms: \(rooms.count)")
    }
}

// Create a person without a residence
let john = Person()

// Try to print number of rooms safely
john.residence?.printNumberOfRooms()  // Nothing prints because residence is nil

// Add a residence
john.residence = Residence()

// Add rooms safely
john.residence?.addRoom(name: "Living Room")
john.residence?.addRoom(name: "Kitchen")

// Print number of rooms again
john.residence?.printNumberOfRooms()
OutputSuccess
Important Notes

Time complexity: Optional chaining itself is O(1) because it just checks for nil and accesses properties or calls methods.

Space complexity: No extra space is used beyond the objects themselves.

Common mistake: Forgetting that optional chaining returns an optional, so you might need to unwrap the result.

Use optional chaining when you want to safely access or call on optionals without many if-let checks. Use if-let if you want to unwrap and use the value immediately.

Summary

Optional chaining safely accesses properties or methods on optionals.

It stops and returns nil if any part is nil, avoiding crashes.

It returns an optional value, so you may need to unwrap it later.

Practice

(1/5)
1. What does the ?. operator do in Swift when used with optionals?
easy
A. It forces unwraps the optional and crashes if nil.
B. It converts the optional to a non-optional value automatically.
C. It safely accesses a property or method and returns nil if the optional is nil.
D. It assigns a default value if the optional is nil.

Solution

  1. Step 1: Understand optional chaining purpose

    The ?. operator is used to safely access properties or methods on an optional value.
  2. Step 2: Behavior when optional is nil

    If the optional is nil, the chaining stops and returns nil instead of crashing.
  3. Final Answer:

    It safely accesses a property or method and returns nil if the optional is nil. -> Option C
  4. Quick Check:

    Optional chaining = safe access with nil return [OK]
Hint: Remember: ? stops if nil, no crash happens [OK]
Common Mistakes:
  • Confusing optional chaining with forced unwrapping
  • Thinking it unwraps optionals automatically
  • Assuming it provides default values
2. Which of the following is the correct syntax to safely access the name property of an optional person object using optional chaining?
easy
A. person->name
B. person!.name
C. person.name?
D. person?.name

Solution

  1. Step 1: Identify correct optional chaining syntax

    Optional chaining uses ?. between the optional variable and the property.
  2. Step 2: Check each option

    person?.name uses person?.name, which is correct syntax. person!.name forces unwraps with !. person.name? places ? incorrectly. person->name uses invalid operator.
  3. Final Answer:

    person?.name -> Option D
  4. Quick Check:

    Optional chaining syntax = variable?.property [OK]
Hint: Use ?. right before the property to chain safely [OK]
Common Mistakes:
  • Using ! instead of ? for optional chaining
  • Placing ? after the property name
  • Using invalid operators like ->
3. Consider the following Swift code:
class Person {
  var pet: Pet?
}
class Pet {
  var name: String
  init(name: String) { self.name = name }
}

let person = Person()
let petName = person.pet?.name
print(petName)

What will be printed?
medium
A. Optional(nil)
B. nil
C. An empty string
D. Runtime error

Solution

  1. Step 1: Analyze the optional chaining result

    Since person.pet is nil (not assigned), person.pet?.name returns nil of type String?.
  2. Step 2: Understand print output of optional nil

    Printing an optional value that is nil in Swift shows Optional(nil) because the variable itself is an optional.
  3. Final Answer:

    Optional(nil) -> Option A
  4. Quick Check:

    print(String? nil) = Optional(nil) [OK]
Hint: Printing optional nil shows 'Optional(nil)', not 'nil' [OK]
Common Mistakes:
  • Thinking print shows nil
  • Expecting empty string output
  • Thinking it causes runtime error
4. The following Swift code causes a compile error. What is the mistake?
struct Car {
  var owner: Person?
}

let car = Car()
let ownerName = car.owner?.name!
medium
A. Using forced unwrap (!) after optional chaining without parentheses
B. Missing initialization of car variable
C. Incorrect use of optional chaining operator
D. Person type does not have a name property

Solution

  1. Step 1: Identify forced unwrap misuse

    The code uses car.owner?.name! which tries to force unwrap the property without parentheses.
  2. Step 2: Correct syntax for forced unwrap after optional chaining

    Forced unwrap must be applied to the entire optional chaining expression with parentheses like (car.owner?.name)!.
  3. Final Answer:

    Using forced unwrap (!) after optional chaining without parentheses -> Option A
  4. Quick Check:

    Force unwrap after optional chaining needs parentheses [OK]
Hint: Wrap optional chain in () before ! to force unwrap [OK]
Common Mistakes:
  • Forgetting parentheses around optional chain before !
  • Assuming optional chaining can be forced unwrapped directly
  • Ignoring compiler error details
5. Given the following classes:
class Address {
  var city: String?
}
class User {
  var address: Address?
}

let user = User()

Which code safely prints the city name if it exists, or "Unknown" if city or address is nil?
hard
A. print(user.address.city ?? "Unknown")
B. print(user.address?.city ?? "Unknown")
C. print(user.address!.city!)
D. print(user.address?.city!)

Solution

  1. Step 1: Understand optional chaining with nil coalescing

    Using user.address?.city safely accesses city, returning nil if address or city is nil.
  2. Step 2: Use nil coalescing operator to provide default

    The ?? "Unknown" provides "Unknown" if the optional is nil, avoiding crashes.
  3. Final Answer:

    print(user.address?.city ?? "Unknown") -> Option B
  4. Quick Check:

    Optional chaining + ?? = safe access with default [OK]
Hint: Combine ?. with ?? to provide default value safely [OK]
Common Mistakes:
  • Forcing unwraps causing runtime crashes
  • Not handling nil for nested optionals
  • Using optional chaining without default fallback
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard