class Person {
let name: String
init(name: String) {
self.name = name
print("\(name) initialized.")
}
deinit {
print("\(name) deallocated.")
}
func performTask(completion: @escaping () -> Void) {
// Simulate an asynchronous task
DispatchQueue.global().async {
print("\(self.name) is performing a task.")
completion()
}
}
}
class TaskManager {
var taskCallback: (() -> Void)?
func assignTaskToPerson(_ person: Person) {
// Using a strong reference, which may lead to a retain cycle
// Uncommenting the line below would create a strong reference cycle
// person.performTask(completion: { self.taskCallback?() })
// Using 'weak' to avoid a strong reference cycle
// person.performTask(completion: { [weak self] in self?.taskCallback?() })
// Using 'unowned' assuming that the person will outlive the task manager
person.performTask(completion: { [unowned self] in self.taskCallback?() })
}
}
// Example usage:
var person: Person? = Person(name: "John")
var taskManager: TaskManager? = TaskManager()
taskManager?.taskCallback = {
print("Task completed.")
}
// Uncommenting the next line would create a strong reference cycle
// taskManager?.assignTaskToPerson(person!)
// Using 'weak' to avoid a strong reference cycle
// taskManager?.assignTaskToPerson(person!)
// Using 'unowned' assuming that the person will outlive the task manager
taskManager?.assignTaskToPerson(person!)
// Simulate deallocation
person = nil
taskManager = nil
// Output:
// John initialized.
// Task completed.
// John is performing a task.
// John deallocated.