Reputation: 3246
I have recently reported a crash in my app, and I've found out what is happening and I need some help/best practices/best approach to this issue.
I have a pushed UICollectionViewController
that on viewDidLoad
queries the server to fetch some data to fill the UICollectionView
.
My problem here is, if I push this UICollectionViewController
and then tap the back button fast - the background thread still continues to fetch the server data, but when the data is fetched I update the UICollectionView
with the performBatchUpdates()
and my app crashes.
Here it happens because the app is attempting to reload data on a view that's not visible anymore.
What's the best practice here?
Is there any way to "abort" collection view updates if I'm moving back to the previous VC?
something like:
if self.isMovingFromParentViewController { /* abort any update here? */ }
Thanks
Upvotes: 0
Views: 264
Reputation: 1895
You can use DispatchWorkItem for achieving this as follows
let backgroundQueue = DispatchQueue.global()
var backgroundTask: DispatchWorkItem!
backgroundTask = DispatchWorkItem { [weak self] in
// Perform background task
if !backgroundTask.isCancelled {
return to main Queue
}
backgroundTask = nil // resolve strong reference cycle
}
backgroundQueue.async(execute: backgroundTask)
// When you want to cancel the task
backgroundQueue.async { [weak backgroundTask] in
backgroundTask?.cancel()
}
Upvotes: 1
Reputation: 642
This is desirable in many cases where we should abort all the Server request. I prefer to perform all the clean up in the
deinit() {
// Abort all your APIs and asynchronous call
// Release all dependency
}
Along with this, always have a weak reference of your controllers and then perform optional binding in the response of the Asynchronous call.
Almofire.request(reqData: param, method: get.....) {
[weak self] response in
guard let safeSelfRef = self, let safeCollectionView =
safeSelfRef.collectionView else { return }
//Update view here
}
Upvotes: 0