Sometimes two objects keep each other alive by holding strong references. This causes a memory problem called a cycle. Weak references help stop this by not keeping the other object alive.
Weak references to break cycles in Swift
class SomeClass { weak var otherObject: OtherClass? }
Use the weak keyword before the variable to make it a weak reference.
Weak references must be optional because the referenced object can disappear (become nil).
Person class has a weak reference to Apartment to avoid a cycle.class Person { var name: String weak var apartment: Apartment? init(name: String) { self.name = name } }
Apartment class has a strong reference to Person.class Apartment { let unit: String var tenant: Person? init(unit: String) { self.unit = unit } }
john and unit4A refer to each other, but john.apartment is weak, so no cycle occurs.let john = Person(name: "John") let unit4A = Apartment(unit: "4A") john.apartment = unit4A unit4A.tenant = john
This program creates a Person and an Apartment that refer to each other. The Person holds a weak reference to the Apartment. When both variables are set to nil, both objects are properly cleaned up because there is no strong cycle.
class Person { let name: String weak var apartment: Apartment? init(name: String) { self.name = name print("Person \(name) is created") } deinit { print("Person \(name) is being deinitialized") } } class Apartment { let unit: String var tenant: Person? init(unit: String) { self.unit = unit print("Apartment \(unit) is created") } 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
Weak references do not increase the reference count of the object.
If the referenced object is deallocated, the weak reference automatically becomes nil.
Use unowned references only when you are sure the referenced object will never be nil during the lifetime of the reference.
Weak references help avoid memory cycles by not keeping objects alive.
They must be optional because the object they point to can disappear.
Use weak references in relationships where one object should not own the other strongly.
Practice
weak references in Swift?Solution
Step 1: Understand what strong reference cycles are
Strong reference cycles happen when two objects hold strong references to each other, preventing deallocation.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.Final Answer:
To prevent strong reference cycles and allow objects to be deallocated -> Option BQuick Check:
Weak references prevent cycles = C [OK]
- Thinking weak makes variables constant
- Confusing weak with performance optimization
- Assuming weak creates copies
Person in Swift?Solution
Step 1: Understand weak reference syntax
Weak references must be declared withweak varand must be optional because the referenced object can be nil.Step 2: Check each option
weak var friend: Person? usesweak var friend: Person?, which is correct syntax.Final Answer:
weak var friend: Person? -> Option AQuick Check:
Weak references use 'weak var' and optional type = A [OK]
- Using 'let' with weak
- Not making the type optional
- Placing 'weak' after 'var'
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?
Solution
Step 1: Understand the references
TheOwnerhas a strong reference toPet, andPethas a weak reference back toOwner.Step 2: Evaluate the print statement
The expressionowner.pet!.owner! === ownerchecks if the pet's owner is the same instance asowner. Sincepet.ownerweakly referencesowner, this is true.Final Answer:
true -> Option CQuick Check:
Weak reference points back correctly = true [OK]
- Thinking weak reference becomes nil immediately
- Confusing identity check with equality
- Expecting compilation error due to weak
class A {
var b: B?
}
class B {
var a: A?
}
let a = A()
let b = B()
a.b = b
b.a = aHow can you fix this cycle?
Solution
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.Step 2: Break the cycle with weak reference
Changing the reference from B to A toweak var a: A?breaks the cycle because B no longer strongly owns A.Final Answer:
Changeain class B to a weak reference -> Option AQuick Check:
Break cycle by making one side weak = D [OK]
- Making both references weak (loses ownership)
- Making the wrong reference weak
- Using unowned incorrectly causing crashes
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?Solution
Step 1: Analyze ownership
ATeacherowns manyStudents, so it should hold strong references to them.Step 2: Avoid cycle by weak reference
EachStudentshould hold a weak reference back to itsTeacherto avoid a strong cycle.Final Answer:
Teacherholds strong references toStudents;Studentholds a weak reference toTeacher-> Option DQuick Check:
Owner strong, back weak = B [OK]
- Making owner reference weak
- Making both references strong causing cycles
- Making both references weak losing ownership
Ready to prove it?
Pass the test and this pattern moves unknown
