Swift 完成处理程序,用于在运行其他任务之前完成任务

Swift 完成处理程序,用于在运行其他任务之前完成任务,swift,completionhandler,Swift,Completionhandler,我真的把自己绑在一个结里,对如何按照我希望的顺序执行任务感到非常困惑 我有函数从服务器数据构建一个数组,并返回一个结果,即数组。-这可以很好地工作并返回结果 完成此操作后(两次),我想运行另一个函数。出于某种原因,目前我正在尝试将这些函数嵌入另一个函数中,其中包含一个完成块,一旦这两个函数完成并返回数据,该块将返回true,但我尝试的方式是在函数完成之前返回结果 func getCollectionArrays(_ block: ((Bool) -> Void)? = nil) {

我真的把自己绑在一个结里,对如何按照我希望的顺序执行任务感到非常困惑

我有函数从服务器数据构建一个数组,并返回一个结果,即数组。-这可以很好地工作并返回结果

完成此操作后(两次),我想运行另一个函数。出于某种原因,目前我正在尝试将这些函数嵌入另一个函数中,其中包含一个完成块,一旦这两个函数完成并返回数据,该块将返回true,但我尝试的方式是在函数完成之前返回结果

func getCollectionArrays(_ block: ((Bool) -> Void)? = nil) {

    var resultPack: Bool!
    var resultPart: Bool!

        BuildArray.buildArrayFromQuery(queryForCollection: "Pack", sender: self, completeBlock: { (result) in

            if result != nil {

                resultPack = true
            }

        })

                BuildArray.buildArrayFromQuery(queryForCollection: "Part", sender: self, completeBlock: { (result) in

                    if result != nil {

                        resultPart = true
                    }

                })

    // this is returning nil because there isn't enough time for "BuildArray.buildArrayFromQuery" to run
    if resultPack == true && resultPart == true {

        block!(true)

    }

}
将下一步移到前一个闭包中。继续筑巢。像这样:

func getCollectionArrays(_ block: ((Bool) -> Void)? = nil) {
    var resultPack: Bool!
    var resultPart: Bool!
    BuildArray.buildArrayFromQuery(queryForCollection: "Pack", sender: self, completeBlock: { (result) in
        if result != nil {
            resultPack = true
        }
        // next step, nested in this closure
        BuildArray.buildArrayFromQuery(queryForCollection: "Part", sender: self, completeBlock: { (result) in
            if result != nil {
                resultPart = true
            }
            // next step, nested in _this_ closure
            if resultPack == true && resultPart == true {
                block!(true)
            }
        })
    })
}
将下一步移到前一个闭包中。继续筑巢。像这样:

func getCollectionArrays(_ block: ((Bool) -> Void)? = nil) {
    var resultPack: Bool!
    var resultPart: Bool!
    BuildArray.buildArrayFromQuery(queryForCollection: "Pack", sender: self, completeBlock: { (result) in
        if result != nil {
            resultPack = true
        }
        // next step, nested in this closure
        BuildArray.buildArrayFromQuery(queryForCollection: "Part", sender: self, completeBlock: { (result) in
            if result != nil {
                resultPart = true
            }
            // next step, nested in _this_ closure
            if resultPack == true && resultPart == true {
                block!(true)
            }
        })
    })
}

仅供参考-
阻止!(true)
如果
nil
将崩溃。不要强制展开可选的.FYI-
块!(true)
如果
nil
将崩溃。不要强制打开可选的。出于某种原因,我认为重复嵌套绝对不是一个好主意。GCD嵌套通常深入到很多层次(切换到后台线程,然后切换到主线程…)。基本上,当事情是异步的时,这种嵌套是使事情按您想要的顺序发生的唯一方法。这就是异步的意思。不要使用
block。如果
block
nil
(这是默认值),您的代码将崩溃。是的,请使用
block?()
@Pippo-关于嵌套,是的,如果您执行太多次,它可能会变得笨拙(例如,假设您有十几个级别的嵌套调用…这太疯狂了)。但是你只要把它们分成不同的方法,它就能保持它的干净。或者你可以使用承诺/未来(比如PromiseKit或RXPromise)。或者,您可以对依赖项使用操作。但只要有两个层次的筑巢,我就不会担心了。出于某种原因,我认为重复筑巢绝对不是一个好主意。GCD嵌套通常深入到很多层次(切换到后台线程,然后切换到主线程…)。基本上,当事情是异步的时,这种嵌套是使事情按您想要的顺序发生的唯一方法。这就是异步的意思。不要使用
block。如果
block
nil
(这是默认值),您的代码将崩溃。是的,请使用
block?()
@Pippo-关于嵌套,是的,如果您执行太多次,它可能会变得笨拙(例如,假设您有十几个级别的嵌套调用…这太疯狂了)。但是你只要把它们分成不同的方法,它就能保持它的干净。或者你可以使用承诺/未来(比如PromiseKit或RXPromise)。或者,您可以对依赖项使用操作。但只要有两层筑巢,我就不会担心了。