Да, вы можете вкладывать отправку в одну очередь внутри отправки в другую очередь. Мы часто так делаем.
Но будьте очень осторожны. Недостаточно просто перенести асинхронную отправку в основную очередь с отправкой из вашей очереди синхронизации. Ваш первый пример не является потокобезопасным. Этот массив, к которому вы обращаетесь из основного потока, может изменяться из вашей очереди синхронизации:
Это условие гонки потому что потенциально у вас есть несколько потоков (поток вашей очереди синхронизации и основной поток), взаимодействующих с одной и той же коллекцией. Вместо того, чтобы ваш отправленный блок в основную очередь просто взаимодействовал objects
напрямую, вы должны сделать его копию, и это то, на что вы ссылаетесь при отправке в главную очередь.
Например, вы можете хочу сделать следующее:
func process(completion: @escaping (String) -> Void) {
syncQueue.sync {
let result = ... // note, this runs on thread associated with `syncQueue` ...
DispatchQueue.main.async {
completion(result) // ... but this runs on the main thread
}
}
}
Это гарантирует, что основная очередь не взаимодействует с какими-либо внутренними свойствами этого класса, а просто result
, созданный в этом замыкании, передается syncQueue
.
Заметьте, все это не связано с тем, что он является одиночным. Но так как вы подняли topi c, я бы посоветовал не использовать синглтоны для данных модели. Это нормально для приемников, контроллеров без сохранения состояния и т. П., Но обычно не рекомендуется для данных модели.
Я бы определенно не рекомендовал инициировать обновления элементов управления пользовательского интерфейса непосредственно из синглтона. Я был бы склонен предоставить эти закрытия обработчиков завершения методов, и позволить вызывающей стороне позаботиться о полученных обновлениях пользовательского интерфейса. Конечно, если вы хотите отправить замыкание в основную очередь (для удобства, что часто встречается во многих сторонних API), это нормально. Но синглтон не должен заходить и обновлять элементы управления самим пользовательским интерфейсом.
Я предполагаю, что вы сделали все это только в иллюстративных целях, но я добавил это слово предостережения будущим читателям, которые могут не оценить эти беспокойство.