0
0
Swiftprogramming~20 mins

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

Choose your learning style9 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.