Bird
Raised Fist0
Swiftprogramming~10 mins

Weak references to break cycles in Swift - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Weak references to break cycles
Create Object A
↓
Create Object B
↓
A strong reference to B
↓
B strong reference to A?
↓
Strong reference cycle
↓
Use weak reference in B to A
↓
No cycle, objects deallocated
This flow shows how two objects referencing each other strongly cause a cycle, and how using a weak reference breaks it to allow deallocation.
Execution Sample
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
  weak var tenant: Person?
  init(unit: String) { self.unit = unit }
  deinit { print("Apartment \(unit) is being deinitialized") }
}
Defines two classes where Apartment holds a weak reference to Person to avoid a strong reference cycle.
Execution Table
StepActionPerson instanceApartment instanceReference TypeOutput
1Create Person named AlicePerson(name: Alice)nilN/A
2Create Apartment unit 4APerson(name: Alice)Apartment(unit: 4A)N/A
3Set Alice.apartment = 4APerson(name: Alice) strong ref to Apartment(4A)Apartment(unit: 4A)Strong
4Set 4A.tenant = Alice (weak)Person(name: Alice)Apartment(unit: 4A) weak ref to Person(Alice)Weak
5Set Person and Apartment to nilnilnilN/APerson Alice is being deinitialized Apartment 4A is being deinitialized
6EndnilnilN/ABoth objects deallocated, no cycle
💡 Both Person and Apartment references are nil, weak reference prevents cycle, so deinit called.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4After Step 5
personnilPerson(name: Alice)Person(name: Alice)Person(name: Alice)nil
apartmentnilApartment(unit: 4A)Apartment(unit: 4A)Apartment(unit: 4A)nil
person.apartmentnilnilApartment(unit: 4A)Apartment(unit: 4A)nil
apartment.tenantnilnilnilPerson(name: Alice) (weak)nil
Key Moments - 3 Insights
Why does using a strong reference from Apartment to Person cause a memory leak?
Because both Person and Apartment hold strong references to each other (see step 3), neither can be deallocated, causing a cycle. The execution_table shows no deinit output if both references are strong.
What does the 'weak' keyword do in the Apartment class?
It makes the reference to Person non-owning, so it doesn't increase the reference count. This allows Person to be deallocated when no other strong references exist, as shown by the deinit messages in step 5.
Why do we see deinitialization messages at step 5?
Because both person and apartment variables are set to nil, and the weak reference prevents a cycle, so both objects are freed and their deinit methods run, printing the messages.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 4. What type of reference does Apartment hold to Person?
AStrong reference
BWeak reference
CUnowned reference
DNo reference
💡 Hint
Check the 'Reference Type' column at step 4 in the execution_table.
At which step do both Person and Apartment get deallocated?
AStep 3
BStep 4
CStep 5
DStep 6
💡 Hint
Look at the 'Output' column for deinit messages in the execution_table.
If Apartment.tenant was a strong reference instead of weak, what would happen at step 5?
ANeither object deallocates (memory leak)
BBoth objects deallocate normally
COnly Person deallocates
DOnly Apartment deallocates
💡 Hint
Refer to the key_moments explanation about strong reference cycles causing memory leaks.
Concept Snapshot
Swift classes can create strong reference cycles when two objects hold strong references to each other.
Use 'weak' keyword to make one reference non-owning.
Weak references do not increase reference count.
This breaks cycles and allows ARC to deallocate objects.
Deinit methods confirm when objects are freed.
Full Transcript
This example shows two Swift classes, Person and Apartment, where Person has a strong reference to Apartment, and Apartment has a weak reference to Person. The flow starts by creating instances of both classes. Person's apartment property is set to the Apartment instance with a strong reference. Apartment's tenant property is set to the Person instance with a weak reference. This setup prevents a strong reference cycle. When both variables are set to nil, the weak reference allows ARC to deallocate both objects, confirmed by their deinit print statements. The execution table traces each step, showing how references change and when deinitialization occurs. Key moments clarify why weak references are needed to avoid memory leaks caused by cycles. The visual quiz tests understanding of reference types and deallocation timing. The snapshot summarizes the concept for quick recall.

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