Если uploadFailed(for id: String)
, uploadSuccess()
и updateOnStart(_ id: String)
вызываются из одного потока (основной поток потока 1), я понимаю, что нам не понадобится синхронизированная очередь. Что делать, если функции вызываются из разных потоков для каждой загрузки. Где я могу обеспечить синхронизацию? Будет ли это и загрузка, и состояние, или только состояние?
enum FlowState {
case started(uploads: [String])
case submitted
case failed
}
class Session {
var state: FlowState
let syncQueue: DispatchQueue = .init(label: "Image Upload Sync Queue",
qos: .userInitiated,
attributes: [],
autoreleaseFrequency: .workItem)
init(state: FlowState) {
self.state = state
}
mutating func updateOnStart(_ id: String) {
guard case .started(var uploads) = state else {
return
}
uploads.append(id)
state = .started(uploads)
}
mutating func uploadFailed(for id: String) {
guard case .started(var uploads) = state else {
return
}
uploads.removeAll { $0 == id }
if uploads.isEmpty {
state = .failed
} else {
state = .started(uploads)
}
}
mutating func uploadSuccess() {
state = .submitted
}
}
Синхронизируем ли мы операцию и состояние массива uploads
, как показано ниже?
syncQueue.sync {
uploads.append(id)
state = .started(uploads)
}
syncQueue.sync {
uploads.removeAll { $0 == id }
if uploads.isEmpty {
state = .failed
} else {
state = .started(uploads)
}
}
ИЛИ
syncQueue.sync {
state = .started(uploads)
}
syncQueue.sync {
if uploads.isEmpty {
state = .failed
} else {
state = .started(uploads)
}
}
Обработчик завершения сетевого вызова может обновить свойство Session
state
. Например, пользователь выбирает 10 изображений и загружает их. По завершении это может быть неудачей или успехом. Для каждого загружаемого нами изображения мы кэшируем ресурс id
и удаляем его, если загрузка не удалась. Когда не удается загрузить все изображения, мы обновляем статус .failed
. Мы просто заботимся об одном загружаемом изображении. Когда загружается одно изображение, мы обновляем статус до .submitted