dispatch group:for-loop中的for-loop*和*async调用

mle*_*coz 2 asynchronous grand-central-dispatch ios swift

我理解如何在简单的for循环中使用调度组.但是,我有一个更复杂的for循环与更多的异步调用内它.我希望在执行组完成代码之前完成所有异步调用.我试图在这个答案中应用原则无济于事 - 我可以使用不在循环中的调度组吗?.这是我的代码,基于我在该链接中观察到的技术:

let group = DispatchGroup()

for ref in self.notifsRefList {
    group.enter()
    self.db.fetch(withRecordID: ref.recordID) { notifRecord, notifErr in
        print("async call")
        if notifErr == nil {

            // do stuff

            if let ref = notifRecord?.object(forKey: POST) as! CKReference? {
                group.enter()
                self.db.fetch(withRecordID: ref.recordID) { postRecord, err in
                    print("async call")
                    if err == nil {
                        // do stuff
                        group.leave()
                    }
                    else {
                        print("\(err)")
                        group.leave()
                    }
                }
            }
            if let ref = notifRecord?.object(forKey: USER_NOTIF) as! CKReference? {
                self.db.fetch(withRecordID: ref.recordID) { userRecord, err2 in
                    group.enter()
                    print("async call")
                    if err2 == nil {
                        // do stuff
                        group.leave()
                    }
                    else {
                        print("\(err2)")
                        group.leave()
                    }
                }
            }
            if let ref = notifRecord?.object(forKey: LIBRARY_ITEM) as! CKReference? {
                self.db.fetch(withRecordID: ref.recordID) { libRecord, err3 in
                    group.enter()
                    print("async call")
                    if err3 == nil {
                        // do stuff                        
                        group.leave()
                    }
                    else {
                        print("\(err3)")
                        group.leave()
                    }
                }
            }

            group.leave()

        }
        else {
            print("\(notifErr)")
            group.leave()
        }
    }

}


group.notify(queue: .main, execute: { // executed after all async calls in for loop finish
    print("done with all async calls")
    // do stuff
})
Run Code Online (Sandbox Code Playgroud)

从我包含的打印语句中,我知道我的异步调用是不正确的:有时"完成所有异步调用"在所有"异步调用"实例之前打印.如何让这个调度组正常工作的任何帮助将不胜感激.谢谢!

rma*_*ddy 7

问题是第二次和第三次内部异步调用.您正在group.enter()完成块内调用,而不是在异步调用之前调用.

也没有必要这么多电话leave.

你需要按如下方式移动两个:

let group = DispatchGroup()

for ref in self.notifsRefList {
    group.enter()
    self.db.fetch(withRecordID: ref.recordID) { notifRecord, notifErr in
        print("async call")
        if notifErr == nil {

            // do stuff

            if let ref = notifRecord?.object(forKey: POST) as! CKReference? {
                group.enter()
                self.db.fetch(withRecordID: ref.recordID) { postRecord, err in
                    print("async call")
                    if err == nil {
                        // do stuff
                    }
                    else {
                        print("\(err)")
                    }
                    group.leave()
                }
            }
            if let ref = notifRecord?.object(forKey: USER_NOTIF) as! CKReference? {
                group.enter()
                self.db.fetch(withRecordID: ref.recordID) { userRecord, err2 in
                    print("async call")
                    if err2 == nil {
                        // do stuff
                    }
                    else {
                        print("\(err2)")
                    }
                    group.leave()
                }
            }
            if let ref = notifRecord?.object(forKey: LIBRARY_ITEM) as! CKReference? {
                group.enter()
                self.db.fetch(withRecordID: ref.recordID) { libRecord, err3 in
                    print("async call")
                    if err3 == nil {
                        // do stuff                        
                    }
                    else {
                        print("\(err3)")
                    }
                    group.leave()
                }
            }
        }
        else {
            print("\(notifErr)")
        }
        group.leave()
    }
}

group.notify(queue: .main, execute: { // executed after all async calls in for loop finish
    print("done with all async calls")
    // do stuff
})
Run Code Online (Sandbox Code Playgroud)