【问题标题】:Unable to break loop with semaphore无法用信号量打破循环
【发布时间】:2021-10-11 05:45:40
【问题描述】:

我正在尝试使用semaphoreDispatchWorkItem 中添加异步任务列表。

 func performStickerWorkItems(_ stickers: [String]) {
    let queue = DispatchQueue.global(qos: .background)
    workItem = DispatchWorkItem { [weak self] in
        for sticker in stickers {
            guard let item = self?.workItem, !item.isCancelled else {
                print("cancelled")
                break
            }
            let semaphore = DispatchSemaphore(value: 0)
            self?.addSticker(sticker: sticker) {
                print("S: \(sticker)")
                semaphore.signal()
            }
            semaphore.wait()
        }
        
        self?.workItem = nil
    }
    
    queue.async(execute: workItem!)
    workItem?.notify(queue: .main) {
        self.updateButton(false)
    }
}

如果我回去,我希望它打破循环并处理。为此,我使用cancel 方法取消DispatchWorkItem,但它不会中断循环。

@IBAction func backWasPressed(_ sender: Any) {
    workItem?.cancel()
    navigationController?.popViewController(animated: true)
}

当我按下返回按钮时,有什么解决方案可以打破semaphore 的循环和过程?

【问题讨论】:

  • semaphore.wait() 之后放置一条打印语句,并确保在您的addSticker 函数执行完成后发出信号。
  • @Kozmotronik 它发出信号

标签: swift for-loop dispatchsemaphore dispatchworkitem


【解决方案1】:

DispatchWorkItem 文档中说:

取消不会影响已经开始的工作项的执行。

由于您的工作项已经开始执行,您需要找到另一种解决方法来取消该工作。您也可以使用单独的Thread,因为它符合您的需求,因为它确实具有有效的取消支持。

【讨论】:

    【解决方案2】:

    从主线程中取消它

    DispatchQueue.main.async {
       workItem?.cancel()
       workItem = nil
    }
    

    【讨论】:

    • 它不工作
    • 我已经更新了我的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 2014-02-06
    • 2013-03-08
    • 1970-01-01
    • 2012-04-02
    • 2023-03-03
    • 1970-01-01
    相关资源
    最近更新 更多