Может ли кто-нибудь дать совет о том, как блокировать потоки в Swift? В частности, у меня есть код, отделяющий модель от представления. Модель обрабатывает добавление, обновление и удаление по отдельности перед фиксацией для доступа к представлению. У меня есть код, который работает в фоновом потоке, чтобы основной поток оставался красивым и быстрым. Приведенный ниже пример кода похож на тот, что я реализовал, и он работает. Однако меня беспокоит, что это слишком сложно с DispatchQueue и блокировками. Я не знаю лучшего способа блокировки между потоками, и это, кажется, работает, но я уверен, что кто-то умнее меня может показать более элегантное решение? Приветствуются любые советы.
class MyClass {
private let model = MyDataModel()
private let syncQueue = DispatchQueue(label: "MyClass")
private let lock = NSLock()
/**
This function can be called from several different places on several different threads.
*/
func processAdds() {
assert(!Thread.isMainThread)
// Ensure no other thread sneaks in and modifies the model while we're working.
syncQueue.sync {
self.lock.lock() // Is this overkill?
// Modify the model.
self.model.calculatePendingAdds()
// Commit the model.
self.model.commit()
// Do some long running stuff with the committed data.
self.model.doStuff()
DispatchQueue.main.async {
self.updateTheUI() // Must be done on the main thread but we don't want another background thread sneaking in and modifying the model.
// Only release the lock when this main thread async block is finished.
self.lock.unlock() // I think this is not overkill because I can't exit the syncQueue before the main thread is finished updating the UI.
}
}
/**
This function can be called from several different places on several different threads.
*/
func processDeletes() {
assert(!Thread.isMainThread)
// Ensure no other thread sneaks in and modifies the model while we're working.
syncQueue.sync {
self.lock.lock() // Is this overkill?
// Modify the model.
self.model.calculatePendingDeletes()
// Commit the model.
self.model.commit()
// Do some long running stuff with the committed data.
self.model.doStuff()
DispatchQueue.main.async {
self.updateTheUI() // Must be done on the main thread but we don't want another background thread sneaking in and modifying the model.
// Only release the lock when this main thread async block is finished.
self.lock.unlock() // I think this is not overkill because I can't exit the syncQueue before the main thread is finished updating the UI.
}
}
}