代码之家  ›  专栏  ›  技术社区  ›  Josch Hazard

如何使循环等待任务完成

  •  0
  • Josch Hazard  · 技术社区  · 7 年前

    我知道这个话题已经有很多贡献了。我尝试了不同的变体 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
        }
    }
    

    如果Im使用DispatchGroup,Alamofire请求将逐个执行,但整个循环无法识别 holding[name] 控股[名称] 总是 nil 因为循环不会等待。

    编辑:

    根据Mikess和VS answers,我尝试了以下方法:

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

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

    2 回复  |  直到 7 年前
        1
  •  2
  •   Prashant Tukadiya    7 年前

    你有两个选择

    1 ) Semaphore

    2 ) Operation Queues

    Semaphores

    你需要谨慎对待 semaphore.signal() semaphore.wait() 一对

    信号量 可能会阻塞 主螺纹 Dispatch.global.async

    semaphore.wait()
    
    Alamofire.request("https://jsonplaceholder.typicode.com", parameters: parameters).responseJSON { responseData in
    
                         semaphore.signal()
                        holding[name] = result
    
     }
    

    给你,封锁

    问题是完成处理程序在主线程中执行,而主线程已经被信号量锁定。最初调用wait()。所以当完成时,信号量。信号()从未被调用

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

        2
  •  1
  •   Versus    7 年前

    我认为可以使用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
        }
    }