我有此方法
strtoul()
当我在后台单击按钮时从Web服务获得响应时,将调用此方法。当我再次按下按钮时,碰巧该方法正在后台执行,arrayMyGoals中的对象数发生了变化,这导致崩溃。 我想在上一个完成后自动启动另一个后台进程
我该如何实现
答案 0 :(得分:1)
您可以为此使用操作队列。示例:
let operationQueue: OperationQueue = {
let operationQueue = OperationQueue()
operationQueue.qualityOfService = .background
operationQueue.maxConcurrentOperationCount = 1
return operationQueue
}()
func runTask(id: String) {
// optional: cancel all previous operations if about to start a new one
// operationQueue.cancelAllOperations()
operationQueue.addOperation {
var wait = 0
for _ in 0 ..< 10000 {
wait += 1
}
DispatchQueue.main.async {
print("task \(id) finished")
}
}
}
runTask(id: "t1")
runTask(id: "t2")
runTask(id: "t3")
输出:
task t1 finished
task t2 finished
task t3 finished
答案 1 :(得分:0)
我将创建一个串行队列,然后按每个按钮,我将在此串行队列上的进程(例如func增量请求计数()函数)中增加一个计数器,以指示需要发出多少请求。
然后我将在此串行队列上启动一个过程(例如func invokeWebRequestIfNeeded()),该过程检查计数器的值,如果该值大于0,则将其递减并调用您的方法以发出Web请求。
当我从网络上收到响应时,我将进行任何必需的处理(在串行队列上),然后再次调用invokeWebRequestIfNeeded()。
如果在此过程中用户按下按钮,则计数器将为一个或多个,因此invokeWebRequestIfNeeded()将再次调用您的方法。
最终,所需请求的数量将减少为零,并且invokeWebRequestIfNeeded()将退出而无需采取任何措施。
可能会有更多的快捷方式来做到这一点。。。但是当我着急时,我喜欢简单明了的事情。