Ivan Cantarino
Ivan Cantarino

Reputation: 3246

Cancel UICollectionView updates when view is being dismissed

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

Answers (2)

iOS_MIB
iOS_MIB

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

Peeyush karnwal
Peeyush karnwal

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

Related Questions