Bird
Raised Fist0
Swiftprogramming~20 mins

Weak references to break cycles in Swift - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Swift Weak Reference Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Swift code with weak references?

Consider the following Swift code that uses weak references to avoid retain cycles. What will be printed?

Swift
class Person {
    let name: String
    weak var apartment: Apartment?
    init(name: String) { self.name = name }
    deinit { print("Person \(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    var tenant: Person?
    init(unit: String) { self.unit = unit }
    deinit { print("Apartment \(unit) is being deinitialized") }
}

var john: Person? = Person(name: "John")
var unit4A: Apartment? = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john

john = nil
unit4A = nil
A
Person John is being deinitialized
Apartment 4A is being deinitialized
BNo output (memory leak due to retain cycle)
CPerson John is being deinitialized only
DApartment 4A is being deinitialized only
Attempts:
2 left
💡 Hint

Think about how weak references affect object lifetime and deinitialization.

❓ Predict Output
intermediate
2:00remaining
What happens if weak is replaced by strong in this Swift example?

Given the same classes as before, if weak var apartment is changed to var apartment (strong reference), what will be the output after setting john and unit4A to nil?

Swift
class Person {
    let name: String
    var apartment: Apartment?
    init(name: String) { self.name = name }
    deinit { print("Person \(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    var tenant: Person?
    init(unit: String) { self.unit = unit }
    deinit { print("Apartment \(unit) is being deinitialized") }
}

var john: Person? = Person(name: "John")
var unit4A: Apartment? = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john

john = nil
unit4A = nil
A
Person John is being deinitialized
Apartment 4A is being deinitialized
BNo output (retain cycle prevents deinitialization)
CPerson John is being deinitialized only
DApartment 4A is being deinitialized only
Attempts:
2 left
💡 Hint

Consider what happens when two objects strongly reference each other.

🔧 Debug
advanced
2:30remaining
Identify the error causing a retain cycle in this Swift code

Examine the code below. It is intended to avoid retain cycles using weak references. However, a retain cycle still occurs. What is the mistake?

Swift
class Owner {
    let name: String
    weak var pet: Pet?
    init(name: String) { self.name = name }
    deinit { print("Owner \(name) deinitialized") }
}

class Pet {
    let name: String
    var owner: Owner?
    init(name: String) { self.name = name }
    deinit { print("Pet \(name) deinitialized") }
}

var alice: Owner? = Owner(name: "Alice")
var fluffy: Pet? = Pet(name: "Fluffy")
alice!.pet = fluffy
fluffy!.owner = alice

alice = nil
fluffy = nil
AThe owner property in Pet should be weak to break the cycle
BBoth properties should be weak to avoid retain cycles
CThe pet property should not be weak; owner should be weak instead
DNo retain cycle exists; code works correctly
Attempts:
2 left
💡 Hint

Think about which side should hold a weak reference to break the cycle.

📝 Syntax
advanced
1:30remaining
Which option correctly declares a weak reference in Swift?

Choose the correct syntax to declare a weak reference to an instance of class Car in Swift.

Aweak let myCar: Car?
Bvar weak myCar: Car?
Cvar myCar: weak Car?
Dweak var myCar: Car?
Attempts:
2 left
💡 Hint

Remember the order of keywords in Swift property declarations.

🚀 Application
expert
3:00remaining
How many objects remain in memory after this Swift code runs?

Analyze the following Swift code. After setting manager and employee to nil, how many objects remain in memory?

Swift
class Manager {
    let name: String
    var employee: Employee?
    init(name: String) { self.name = name }
    deinit { print("Manager \(name) deinitialized") }
}

class Employee {
    let name: String
    weak var manager: Manager?
    init(name: String) { self.name = name }
    deinit { print("Employee \(name) deinitialized") }
}

var manager: Manager? = Manager(name: "Mia")
var employee: Employee? = Employee(name: "Eli")
manager!.employee = employee
employee!.manager = manager

manager = nil
employee = nil
A2 objects remain; retain cycle prevents deinitialization
B1 object remains; Manager is retained
C0 objects remain; both are deinitialized
D1 object remains; Employee is retained
Attempts:
2 left
💡 Hint

Consider which references are weak and which are strong.

Practice

(1/5)
1. What is the main purpose of using weak references in Swift?
easy
A. To increase the performance of the program by caching values
B. To prevent strong reference cycles and allow objects to be deallocated
C. To make variables constant and unchangeable
D. To create multiple copies of an object automatically

Solution

  1. Step 1: Understand what strong reference cycles are

    Strong reference cycles happen when two objects hold strong references to each other, preventing deallocation.
  2. Step 2: Role of weak references

    Weak references do not increase the reference count, so they help break these cycles and allow memory to be freed.
  3. Final Answer:

    To prevent strong reference cycles and allow objects to be deallocated -> Option B
  4. Quick Check:

    Weak references prevent cycles = C [OK]
Hint: Weak references avoid memory cycles by not owning objects [OK]
Common Mistakes:
  • Thinking weak makes variables constant
  • Confusing weak with performance optimization
  • Assuming weak creates copies
2. Which of the following is the correct syntax to declare a weak reference to an instance of class Person in Swift?
easy
A. weak var friend: Person?
B. weak let friend: Person?
C. weak var friend: Person
D. var weak friend: Person?

Solution

  1. Step 1: Understand weak reference syntax

    Weak references must be declared with weak var and must be optional because the referenced object can be nil.
  2. Step 2: Check each option

    weak var friend: Person? uses weak var friend: Person?, which is correct syntax.
  3. Final Answer:

    weak var friend: Person? -> Option A
  4. Quick Check:

    Weak references use 'weak var' and optional type = A [OK]
Hint: Weak references are always optional vars [OK]
Common Mistakes:
  • Using 'let' with weak
  • Not making the type optional
  • Placing 'weak' after 'var'
3. Consider the following Swift code snippet:
class Owner {
    var pet: Pet?
}

class Pet {
    weak var owner: Owner?
}

let owner = Owner()
let pet = Pet()
owner.pet = pet
pet.owner = owner

print(owner.pet!.owner! === owner)

What is the output of this code?
medium
A. nil
B. false
C. true
D. Compilation error

Solution

  1. Step 1: Understand the references

    The Owner has a strong reference to Pet, and Pet has a weak reference back to Owner.
  2. Step 2: Evaluate the print statement

    The expression owner.pet!.owner! === owner checks if the pet's owner is the same instance as owner. Since pet.owner weakly references owner, this is true.
  3. Final Answer:

    true -> Option C
  4. Quick Check:

    Weak reference points back correctly = true [OK]
Hint: Weak references still point to original object if alive [OK]
Common Mistakes:
  • Thinking weak reference becomes nil immediately
  • Confusing identity check with equality
  • Expecting compilation error due to weak
4. Given the following code, why does it cause a strong reference cycle?
class A {
    var b: B?
}

class B {
    var a: A?
}

let a = A()
let b = B()
a.b = b
b.a = a

How can you fix this cycle?
medium
A. Change a in class B to a weak reference
B. Change b in class A to a weak reference
C. Make both references strong
D. Use unowned for both references

Solution

  1. Step 1: Identify the cycle

    Class A holds a strong reference to B, and B holds a strong reference back to A, causing a cycle.
  2. Step 2: Break the cycle with weak reference

    Changing the reference from B to A to weak var a: A? breaks the cycle because B no longer strongly owns A.
  3. Final Answer:

    Change a in class B to a weak reference -> Option A
  4. Quick Check:

    Break cycle by making one side weak = D [OK]
Hint: Make one side weak to break cycles [OK]
Common Mistakes:
  • Making both references weak (loses ownership)
  • Making the wrong reference weak
  • Using unowned incorrectly causing crashes
5. You have two classes, Teacher and Student, where each Teacher has many Students and each Student has one Teacher. How should you declare the references to avoid strong reference cycles?
hard
A. Teacher holds weak references to Students; Student holds a strong reference to Teacher
B. Both hold weak references
C. Both hold strong references
D. Teacher holds strong references to Students; Student holds a weak reference to Teacher

Solution

  1. Step 1: Analyze ownership

    A Teacher owns many Students, so it should hold strong references to them.
  2. Step 2: Avoid cycle by weak reference

    Each Student should hold a weak reference back to its Teacher to avoid a strong cycle.
  3. Final Answer:

    Teacher holds strong references to Students; Student holds a weak reference to Teacher -> Option D
  4. Quick Check:

    Owner strong, back weak = B [OK]
Hint: Owner holds strong, back reference is weak [OK]
Common Mistakes:
  • Making owner reference weak
  • Making both references strong causing cycles
  • Making both references weak losing ownership
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