如何进行循环,直到任务完成 [英] How to make a loop wait until task is finished

查看:257
本文介绍了如何进行循环,直到任务完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道该主题已经做出了很多贡献.我尝试了 DispatchGroup 的不同变体,但看来我无法使整个循环停止,直到完成某项任务为止.

I know there are a lot of contributions already for this topic. I tried different variations with DispatchGroup, but it seems I'm not able to make the whole loop stop until a certain task is finished.

let names = ["peter", "susan", "john", "peter", "susan", "john"]
var holding = [String: [Double]]()


for i in 0...10 {

    for name in names {

        if holding[name] == nil {
            Alamofire.request("https://jsonplaceholder.typicode.com", parameters: parameters).responseJSON { responseData in

                    // do stuff here
                    holding[name] = result
            }

        } else {
            // do other stuff with existing "holding[name]"

        }

        // if if holding[name] == nil, the whole process should wait
    }
}

如果我使用DispatchGroup,则Alamofire请求将一一执行,但是整个循环无法识别holding[name]是否已经存在.因此holding[name]始终为nil,因为循环不等待.

If I´m using DispatchGroup, the Alamofire requests are executed one by one, but the the whole loop doesn't recognize if holding[name] does already exist. So holding[name] is always nil because the loop doesn't wait.

非常感谢!

根据Mikes和Versus的回答,我尝试了以下操作:

According to Mikes´s and Versus´ answers, I tried the following:

var names = ["peter", "susan", "john", "peter", "susan", "john"]
var holding = [String: [Double]]()

let semaphore = DispatchSemaphore(value: 1)

for i in 0...10 {

    DispatchQueue.global().async { [unowned self] in
        self.semaphore.wait()

        for name in names {

            if holding[name] != nil {
                Alamofire.request("https://jsonplaceholder.typicode.com", parameters: parameters).responseJSON { responseData in

                    // do stuff here
                    holding[name] = result
                    semaphore.signal()
                }

            } else {
                // do other stuff with existing "holding[name]"
                semaphore.signal()

            }

            // if if holding[name] != nil, the wholeprocess should wait
        }
    }
}

但不幸的是,该应用程序崩溃了.我在做什么错了?

But unfortunately the app crashes. What am I doing wrong?

推荐答案

您在这里有两种选择

1)Semaphore

2)Operation Queues

但是在使用Semaphores

您需要注意semaphore.signal()semaphore.wait()

由于Semaphore可能会阻塞主线程,因此所有操作都应在Dispatch.global.async

As Semaphore may block Main Thread so all operation should be done in Dispatch.global.async

semaphore.wait()

Alamofire.request("https://jsonplaceholder.typicode.com", parameters: parameters).responseJSON { responseData in

                     semaphore.signal()
                    holding[name] = result

 }

在这里,您阻塞了主线程

问题在于完成处理程序在主线程中执行,该主线程已被最初调用的semaphore.wait()锁定.因此,当完成发生时,semaphore.signal()永远不会被调用

The problem is that the completion handler gets executed in the main thread, which was already locked by the semaphore.wait() called initially. So when the completion occurs, semaphore.signal() never gets called

您必须选择

 DispatchQueue.global().async { [unowned self] in
        self.semaphore.wait()
        // And other statemetns 

    }

希望对您和其他人有帮助

Hope it is helpful to you and other

这篇关于如何进行循环,直到任务完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆