I am working on a ViewController where I called my viewModel to do a DispatchQueue.async call. After the async task starts and before the end my task ViewController is deinited by pressing the back button. In that case, what will be happened to my async task? Is it gonna hold a thread or a memory block or cause a memory leak? If that happens, is there any way to cancel my async task?
For understanding, I am adding demo classes:
Class A: ViewController {
let viewModel = B()
func callViewModelAsyncFunction() {
viewModel.viewModelAsyncFunction()
}
}
Class B {
private let sessionQueue = DispatchQueue(label: "Session.Queue")
private let sessionGroup = DispatchGroup()
func viewModelAsyncFunction() {
sessionQueue.async {
self.sessionGroup.wait()
self.sessionGroup.enter()
//do my other task signal producer call {
//}
}
}
}
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