Swift DispatchSemaphore 正在冻结应用程序
Posted
技术标签:
【中文标题】Swift DispatchSemaphore 正在冻结应用程序【英文标题】:Swift DispatchSemaphore is freezing the application 【发布时间】:2021-08-24 08:16:14 【问题描述】:我尝试使用 DispatchSemaphore 在循环中运行 API 服务,它冻结了应用程序, 我的要求是我已经调用 API 来获取详细信息列表每个详细信息我有不同的请求,我需要在循环中调用 API,每个 API 都依赖于先前 API 的响应,因此我使用了 DispatchSemaphore 等待和信号方法,但它正在释放应用程序
示例代码:
func DownloadInformation(urlString: String, device: String, indexValue: Int, completion: @escaping (_ requestIndex: Int?) -> (Void))
ApiService.sharedInstance.DownloadHealthInsightDetails(ID: self.equipmentAnalaysisArr[indexValue].id) [self] (serverResponse, error, cardID) -> (Void) in
if(serverResponse != nil && error == nil)
let insightCycleList = serverResponse as? NSDictionary
if (insightCycleList?["error"]) == nil
if let cycle = insightCycleList?["cycles"] as? [AnyObject], cycle.count != 0
let dispatchGroup = DispatchGroup()
let dispatchQueue = DispatchQueue(label: "taskQueue")
let dispatchSemaphore = DispatchSemaphore(value: 0)
for i in 0..<cycle.count
if i < 5
dispatchGroup.enter()
let element = cycle[i]
self.DownloadCycleData(urlString: blob_url , cycleDownloadCompletion: _ in
completion(indexValue)
dispatchSemaphore.signal()
dispatchGroup.leave()
)
dispatchSemaphore.wait()
dispatchGroup.notify(queue: DispatchQueue.main)
print("done")
//
else
self.ShowMessage(index: indexValue, message: self.message)
else
self.ShowMessage(index: indexValue, message: self.message)
谁能给我建议来解决这个问题?
谢谢。
【问题讨论】:
作为对潜在回答者的礼貌,请发布您的真实代码(它是Void
而不是void
)并缩进代码正确。
贴出我的原码请查收
阻塞执行是信号量的唯一工作,这并不奇怪。有点令人惊讶的是,您使用信号量来序列化所有对DownloadCycleData
的调用。你为什么这样做?与 IO 相关的任务从能够并发运行中受益匪浅。
每个响应都依赖于前一个响应,因此我使用信号量
或者我们可以通过其他方式实现这一目标吗?
【参考方案1】:
您没有使用 DispatchQueue(label: "taskQueue")。 但也许你应该考虑在这种情况下使用一些状态机。
if let cycle = insightCycleList?["cycles"] as? [AnyObject], cycle.count != 0
let dispatchQueue = DispatchQueue(label: "taskQueue")
let semaphore = DispatchSemaphore(value: 0)
dispatchQueue.async
for i in 0..<cycle.count
if i < 5
let cycleSemaphore = DispatchSemaphore(value: 0)
let element = cycle[i]
self.DownloadCycleData(urlString: blob_url , cycleDownloadCompletion: _ in
completion(indexValue)
cycleSemaphore.signal()
)
cycleSemaphore.wait()
semaphore.signal()
semaphore.wait()
【讨论】:
谢谢你的建议,我会像你提到的那样添加信号量信号看看 但问题是我们已经在运行后台任务 (ApiService.sharedInstance.DownloadHealthInsightDetails) 如果我们在 dispatchQueue 中执行此操作会再次起作用吗? 那么你就不需要 dispatchQueue 这是不工作的cycleSemaphore.wait() 阻塞整个进程 你提到的上面的代码你使用的是两个不同的信号量吗?以上是关于Swift DispatchSemaphore 正在冻结应用程序的主要内容,如果未能解决你的问题,请参考以下文章
如何将 DispatchSemaphore 与 Alamofire 和 SwiftyJSON 一起使用?
Swift Async - Task.detached 在哪个线程上运行?