У меня есть бэкэнд, который может обрабатывать до 4 одновременных сетевых подключений. Чтобы компенсировать это, я создал массив с именем urlsQueue
, который содержит все параметры, необходимые для каждого сетевого запроса. Приведенный ниже код дает желаемые результаты, если urlsQueue
содержит 4 или менее элементов. Однако, если я введу func downloadBusiness
с 5+ элементами внутри urlsQueue
, приложение зависнет.
func downloadBusinesses(latitude: Double, longitude: Double){
if urlsQueue.isEmpty {return}
let semaphore = DispatchSemaphore(value: 4)
let dispatchGroup = DispatchGroup()
for (index, element) in urlsQueue.enumerated(){
dispatchGroup.enter()
semaphore.wait()
_ = Client.getBusinesses(latitude: latitude, longitude: longitude, offset: element.offset ,completion: { [weak self] (yelpDataStruct, result) in
defer {
semaphore.signal()
dispatchGroup.leave()
}
self?.handleGetNearbyBusinesses(inputData: yelpDataStruct, result: result)
})
}
dispatchGroup.notify(queue: .main) {[weak self] in
self?.runDownloadAgain()
}
}
Если сетевой запрос завершается успешно, я удаляю соответствующее значение из urlsQueue
. В случае сбоя сетевого запроса запись остается внутри urlsQueue
. После перебора каждого элемента в urlsQueue
я повторяю процесс снова, если цикл не пустой. Таким образом, я могу повторно выполнить любые неудачные сетевые запросы.
func runDownloadAgain(){
let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { [weak self] timer in
self?.downloadBusinesses(latitiude: self!.latitude, longitude: self!.longitude)
}
timer.fire()
}
Мне удалось отладить точку останова в приложении в цикле for-enumerated выше. После 4-го раза в цикле все просто останавливается. Если я прохожу программу, я не могу двигаться вперед. Если я настраиваю жестко запрограммированное значение 4 для любого другого целого числа, проблема повторяется, и кодовый блок успешно выполняется только в том случае, если urlsQueue.count
<= x, где x - это значение в <code>DispatchSemaphore(value: x)
Проблема заключается в моем неправильном смешивании dispatchGroup / semaphore / defer. Но я действительно изо всех сил пытаюсь понять, как можно успешно объединить эти элементы, чтобы избежать зависания приложения при ограничении сетевых подключений до 4.