Since no one goona respond to my naive question, I do some experiments, and here is my experiment code on Playgrounds
import Foundation
final class ClassA {
let viewModel: ViewModel
let classB: ClassB
let time: Int
init(viewModel: ViewModel, classB: ClassB, time: Int) {
print("Init Class A")
self.viewModel = viewModel
self.classB = classB
self.time = time
}
func doBackGroundTaskInViewModel() {
viewModel.doBackGroundTask(anotherClass: classB, completion: {
print("Block task is done")
})
}
deinit {
print("Class A deinited and initTime \(time)")
}
}
final class ClassB {
let time: Int
init(time: Int) {
print("Init Class B")
self.time = time
}
deinit {
print("Class B deinited and InitTime:\(time)")
}
func printClassBInformation() {
sleep(2)
print("Claas B still alive")
printCurrentTime()
}
}
final class ViewModel {
private let sessionQueue = DispatchQueue(label: "Session.Queue")
private let sessionGroup = DispatchGroup()
func doBackGroundTask(anotherClass: ClassB, completion: @escaping() -> Void) {
sessionQueue.async {
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
printCurrentTime()
anotherClass.printClassBInformation()
completion()
}
}
}
init() {
print("Init Class ViewModel")
}
deinit {
print("ViewModel deinitd")
}
}
func printCurrentTime () {
let date = Date()
let calendar = Calendar.current
print(calendar.component(.second, from: date))
}
var classA: ClassA? = ClassA(viewModel: .init(), classB: .init(time: 1), time: 1)
printCurrentTime()
classA?.doBackGroundTaskInViewModel()
classA = ClassA(viewModel: .init(), classB: .init(time: 2), time: 2)
classA?.doBackGroundTaskInViewModel()
classA = nil
And experiment result is
Init Class ViewModel
Init Class B
Init Class A
51
Init Class ViewModel
Init Class B
Init Class A
Class A deinited and initTime 1
ViewModel deinitd
Class A deinited and initTime 2
ViewModel deinitd
53
Claas B still alive
55
Block task is done
Class B deinited and InitTime:1
55
Claas B still alive
57
Block task is done
Class B deinited and InitTime:2
From my experiment, I understand that
- Async call can remain in the thread until thread-related task is
completed although the caller class is deinited.
- Also, another point notices that async call-related variables and completion block hold the Memory.