Updated 28 February 2022
Memory management is sometime complicate in asynchronous tasks.
Various objects need to fetch and release memory over time, in order to performed and handled asynchronous call. Async/ Await used to make many kinds of asynchronous operations easier to write.
It requires being careful when it comes to managing the memory in various objects, especially in asynchronous code(async/await)
Let me explain the implicit memory fetching with the example.
For example, we are working on downloadViewController, which downloads and shows the document.
To make our download execute lazily when our view controller is about to be displayed to the user, we’re starting that operation within our view controller’s viewDidLoad
method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
class DownloadViewController: UIViewController { private let documentURL: URL private let urlSession: URLSession override func viewDidLoad(){ super.viewDidLoad() Task { do { let (data, _) = try await urlSession.data(from: documentURL) let decoder = JSONDecoder() let doc = try decoder.decode(Document.self, from: data) ShowDocument(doc) } catch { showErrorView(for: error) } } } private func ShowDocument(_ document: Document) { } private func showErrorView(for error: Error) { } } |
Now, if we see the above code, it does not seem like there is any object fetching memory
We are expecting here, that if we start displaying our DownloadViewController
, then navigate away from it before completing the downloading, that it will be successfully deallocated it. But that’s actually not the case.
As we explain earlier, implicit fetching happens when we create a Task and use await to wait the result of the asychronous task.
Now, if we want to download quite large document and we don’t want to use multiple view controllers and there operations to remain in memory if user quickly navigates between different screens.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class DownloadViewController: UIViewController { override func viewDidLoad(){ super.viewDidLoad() TTask { [weak self, urlSession, documentURL] in do { let (data, _) = try await urlSession.data(from: documentURL) let decoder = JSONDecoder() let doc = try decoder.decode(Document.self, from: data) self?.renderDocument(doc) } catch { self?.showErrorView(for: error) } } } } |
If we want to fetch self weakly , then we have to consistently use that weak sealf reference.
Witrh the above code, our view controller will successfully deallocated.
Conclusion:
It seems technologies like Task
and async/await
solve the asynchronous, memory-related issues.
We still have to careful how objects are fetch and retained. when performing various kinds of async
calls.
For more clarification please read the John Sundell blog Memory management when using async/await in Swift
Hope you liked this post. If you have any other thoughts or comments you can leave your thoughts in the comment section.
For other blogs Please click here
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
Be the first to comment.