多个完成块完成后执行的函数

Function that executes after multiple completion block has finished

我有一个函数,我只想在两个完成块完成时执行(而且无法判断先完成哪个)。以下是我的尝试。然而,它非常混乱,如果我要等待三个或更多的完成块,我会到处都有标志。我想知道是否有更漂亮的方法。

class TestClass: UIViewController {
    var blockOneComplete = false
    var blockTwoComplete = false

    func blockOneDownloadImageDescription(completion:()->Void) {
        downloadAsyncWithCompletion {
            blockOneComplete = true 
            if self.blockTwoComplete == true {
                self.allDataDownloadCompleted()
            } else {
                // Do nothing and wait for block Two to complete
            }
        }
    }

    func blockTwoDownloadImageData(completion:()->Void) {
        downloadAsyncWithCompletion {
            blockTwoComplete = true 
            if self.blockOneComplete == true {
                self.allDataDownloadCompleted()
            } else {
                // Do nothing and wait for block One to complete
            }
        }
    }

    func allDataDownloadComplete() {
        // Execute this funciton after all Async Download has complete
    }
}

-- 更新最终结果 -- 事实证明,该网站中概述的内容正是我所需要的 Using dispatch groups to wait for multiple web services

我相信这不是评论中提到的 SO 问题的重复,因为最终解决方案包括 dispatch_group_enter 和 dispatch_group_leave

如果您不想管理标志,则需要使用 dispatch_group 或使用 RxSwift 等函数式反应式编程库来实现。

但是,您可以只使用一个计数器标志并进行函数调用,或者使用 NSNotification if 是另一个 ViewController.

在我的一个项目中,我需要确保在调用某个函数之前至少完成 4 个 completion block 中的 3 个。我这样做是这样的:

class TestClass: UIViewController {
    var numberOfBlockCompleted = 0

    func blockOneDownloadImageDescription(completion:()->Void) {
        downloadAsyncWithCompletion {
            numberOfBlockCompleted += 1 
            self.allDataDownloadCompleted()
        }
    }

    func blockTwoDownloadImageData(completion:()->Void) {
        downloadAsyncWithCompletion {
            numberOfBlockCompleted += 1 
            self.allDataDownloadCompleted()
        }
    }

    func blockThreeDownloadImageDesc(completion:()->Void) {
        downloadAsyncWithCompletion {
            numberOfBlockCompleted += 1
            self.allDataDownloadCompleted()
        }
    }


    func allDataDownloadComplete() {
        if numberOfBlockCompleted == 3 {
            //do something
        }
    }
}

在我看来,这在很大程度上取决于应用程序的复杂程度。如果只是一个或两个部分,一个标志就足够了。但是,如果该应用程序主要依赖于链式网络调用和从需要等待一个或另一个完成的不同服务器获取,如实时股票应用程序,那么对 GCD 的深入了解或使用功能反应式编程将使您的工作更轻松长 运行.

最好的选择是使用 dispatch_group

class TestClass: UIViewController {

    var group : dispatch_group_t = dispatch_group_create()

    override func viewDidLoad() {
        super.viewDidLoad()
        dispatch_group_notify(group, dispatch_get_main_queue()) { 
            allDataDownloadComplete()
        }
    }

    func blockOneDownloadImageDescription(completion:()->Void) {
        dispatch_group_enter(group)
        downloadAsyncWithCompletion {
            dispatch_group_leave(group)
        }
    }

    func blockTwoDownloadImageData(completion:()->Void) {
        dispatch_group_enter(group)
        downloadAsyncWithCompletion {
            dispatch_group_leave(group)
        }
    }

    func allDataDownloadComplete() {
        // Execute this funciton after all Async Download has complete
    }
}