gpt4 book ai didi

swift - 结合信号量来限制 .notify 的异步请求和调度组与延迟和应用程序卡住

转载 作者:行者123 更新时间:2023-11-28 13:38:02 24 4
gpt4 key购买 nike

我有一个后端可以同时处理最多 4 个网络连接。作为补偿,我创建了一个名为 urlsQueue 的数组,其中包含每个网络请求所需的所有参数。如果 urlsQueue 包含 4 个或更少的元素,下面的代码会产生我想要的结果。但是,如果我在 urlsQueue 中输入包含 5 个以上元素的 func downloadBusiness,应用程序会卡住。

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 是 DispatchSemaphore(value : x)

问题出在我dispatchGroup/semaphore/defer的混用不当。但我真的很想知道如何成功地重新组合这些元素以避免应用程序卡住,同时将网络连接限制为 4。

最佳答案

因为您总是从 URL 队列的索引 0 开始,如果索引 > 3 并丢弃信号量,则退出循环

func downloadBusinesses(latitiude: Double, longitude: Double){
if urlsQueue.isEmpty {return}
let dispatchGroup = DispatchGroup()

for (index, element) in urlsQueue.enumerated(){
if index > 3 { break }
dispatchGroup.enter()
_ = Client.getBusinesses(latitude: latitude, longitude: longitude, offset: element.offset ,completion: { [weak self] (yelpDataStruct, result) in
defer {
dispatchGroup.leave()
}
self?.handleGetNearbyBusinesses(inputData: yelpDataStruct, result: result)
})
}
dispatchGroup.notify(queue: .main) { // GCD closures don't cause retain cycles
self.runDownloadAgain()
}
}

关于swift - 结合信号量来限制 .notify 的异步请求和调度组与延迟和应用程序卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56367104/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com