Added, removed, moved, updated, yeah. That's quite error prone to do right in general case when all these things can happen simultaneously. This is easier with SwiftUI, and if you are limited to UIKit - you may try its iOS 13+ diffable data source API that performs this heavy lifting for you. Interestingly its main apply(snapshot)
call is not limited to the main thread (contrary to the classic reloadRows
/ reloadData
):
Yes, you can do that work on a background queue and update UI on the main thread (or even background thread as discussed above). However, you don't have to protect that data if you only read / modify it on a single background queue... Example:
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
...
NotificationCenter.default.addObserver(forName: Notification.Name(""), object: nil, queue: queue) { n in
dispatchPrecondition(condition: .notOnQueue(.main))
// we are in background
urls = ... // change urls here. single queue access → can be unprotected
// you may apply diffable snapshot here (see above)
let urlsCopy = urls // grab a copy. single queue access → can be unprotected
DispatchQueue.main.async {
... urlsCopy // use urlsCopy here
// you may apply diffable snapshot here (see above)
// or you may apply insert / delete / move / modify updates here manually
}
}