繁体   English   中英

如何进行循环,直到任务完成

[英]How to make a loop wait until task is finished

我知道这个主题已经有很多贡献。 我使用DispatchGroup尝试了不同的变体,但似乎我无法使整个循环停止,直到完成特定任务为止。

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请求将一一执行,但整个循环无法识别到hold holding[name]是否已经存在。 因此, holding[name]始终为nil因为循环不等待。

非常感谢你!

编辑:

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

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
        }
    }
}

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

你有两个选择

1) Semaphore

2) Operation Queues

但是在使用Semaphores之前,您应该三思而后行

您需要对semaphore.signal()semaphore.wait()对保持谨慎

由于Semaphore可能会阻塞主线程,因此所有操作都应在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()永远不会被调用

你必须去

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

    }

希望对您和其他人有帮助

我认为您可以使用DispatchSemaphore停止循环:

let semaphore = DispatchSemaphore(value: 1)
for i in 0...10 {

    for name in names {
        // if signal is 0, loop will be stopped forever,  
        // if signal > 0, loop will continue 
        semaphore.wait()
        if holding[name] == nil {
        Alamofire.request("https://jsonplaceholder.typicode.com", parameters: parameters).responseJSON { responseData in

                // do stuff here
                // release signal to continue current loop(signal + 1)
                semaphore.signal()
                holding[name] = result
            }

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

        }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM