我目前正在玩Grand Central Dispatch并发现了一个名为的课程DispatchWorkItem.文档似乎有点不完整,所以我不确定以正确的方式使用它.我创建了以下代码段,并期待一些不同的东西.我希望在调用cancel它之后该项目将被取消.但由于某种原因,迭代仍在继续.我有什么想法我做错了吗?代码似乎对我来说很好.
@IBAction func testDispatchItems() {
let queue = DispatchQueue.global(attributes:.qosUserInitiated)
let item = DispatchWorkItem { [weak self] in
for i in 0...10000000 {
print(i)
self?.heavyWork()
}
}
queue.async(execute: item)
queue.after(walltime: .now() + 2) {
item.cancel()
}
}
Run Code Online (Sandbox Code Playgroud) 我希望使用Alamofire runTask()能够停止的功能列表中的一系列HTTP请求是使用Alamofire依次发出的。因此,我为需要运行的每个任务设置了一个runTask()函数调用DispatchWorkItem,并将工作项存储在数组中,如下所示:
taskWorkItems.append(DispatchWorkItem { [weak self] in
concurrentQueue!.async {
runTask(task: task)
}
})
Run Code Online (Sandbox Code Playgroud)
然后,我迭代工作项的数组并按如下所示调用perform()函数:
for workItem in taskWorkItems {
workItem.perform()
}
Run Code Online (Sandbox Code Playgroud)
最后,我的应用程序中有一个按钮,当点击该按钮时,我想取消工作项,并且使用以下代码来实现这一目的:
for workItem in taskWorkItems {
concurrentQueue!.async {
workItem.cancel()
print(workItem.isCancelled)
}
}
Run Code Online (Sandbox Code Playgroud)
workItem.isCancelled打印到true; 但是,我在调用的函数中设置了日志,runTask()即使workItem.cancel()被调用和workItem.isCancelled打印,我仍然看到函数正在执行true。我在做什么错,如何停止执行功能?
我使用GCD DispatchWorkItem来跟踪我发送到firebase的数据.
我做的第一件事是声明类型的2个类属性,DispatchWorkItem然后当我准备好将数据发送到firebase时,我用值初始化它们.
第一个属性被命名errorTask.当初始化它cancels的firebaseTask,并将它设置nil,然后打印"errorTask炒鱿鱼".它有一个DispatchAsync Timer,将调用它0.0000000001秒如果errorTask没有之前那么取消.
第二个属性被命名firebaseTask.初始化时,它包含一个将数据发送到firebase的函数.如果firebase回调成功,则errorTask取消并设置为nil,然后打印一个打印语句"firebase callback".我还检查firebaseTask是否被取消.
问题是在到达回调errorTask之前始终运行的代码firebaseTask.该errorTask代码取消firebaseTask,将其设为零,但由于某种原因,firebaseTask仍然运行.我想不通为什么?
print语句支持errorTask首先运行的事实,因为
"errorTask fired"之前总是打印出来"firebase callback was reached".
为什么firebaseTask没有被取消并设置为nil,即使errorTask让这些事情发生了?
在我的实际应用程序中,如果用户向Firebase发送一些数据,则会出现活动指示符.达到firebase回调后,活动指示器将被解除,并向用户显示一条提示已成功的警报.但是,如果活动指示器上没有计时器并且从未达到回调,那么它将永远旋转.将DispatchAsyc after计时器设置为15秒,如果未达到回调,则会显示错误标签.它总是有效的10次中的9次.
但每一次都在
firebaseTask 取消并设置为nil,活动指示器将被取消的errorTask代码块驳回actiInd,示出了errorLabel,并取消firebaseTask,并将其设置到零.一旦firebaseTask被取消并设置为nil,我假设其中的所有内容也将停止,因为从未到达回调. 这可能是我混淆的原因.似乎即使firebaseTask取消并设置为nil,someRef?.updateChildValues(...仍然以某种方式运行,我也需要取消它.
我的代码:
var errorTask:DispatchWorkItem?
var firebaseTask:DispatchWorkItem?
@IBAction func …Run Code Online (Sandbox Code Playgroud) 我点击了 10 次 Web 服务 url 并得到响应。我正在使用Alamofire和SwiftyJSON。这是我的控制器代码
class ViewController: UIViewController {
let dispatchGroup = DispatchGroup()
var weatherServiceURL = "http://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22"
override func viewDidLoad() {
super.viewDidLoad()
start()
}
func start() {
weatherService()
dispatchGroup.notify(queue: .main) {
print("All services complete")
}
}
func weatherService() {
for i in 1...10 {
dispatchGroup.enter()
APIManager.apiGet(serviceName: self.weatherServiceURL, parameters: ["counter":i]) { (response:JSON?, error:NSError?, count:Int) in
if let error = error {
print(error.localizedDescription)
return
}
guard let response = response else { return }
print("\n\(response) \n\(count) …Run Code Online (Sandbox Code Playgroud) grand-central-dispatch ios dispatch-async swift dispatchworkitem