如何在 swift 中的后台进程子函数中 return 一个函数的值

How to return a value to a function while in background process subfunction in swift

我第一次尝试这个解决方案 return 我想 return 它的地方的布尔值。但是,由于 parse.com 函数 saveInBackgroundWithBlock() 是一个无效的 return 函数,我得到了错误 "Unexpected non-void return value in void function".

func saveObjectToParse(gameLocal: Game) -> Bool {
        let game = PFObject(className:"Game")
        game["sport"] = gameLocal.sport.rawValue
        var saved = false
        game.saveInBackgroundWithBlock {
            (success: Bool, error: NSError?) -> Void in
            if (success) {
                print("Object has been saved.")
                saved = true
                return saved
            } else {
                print("parse error")
                return saved
            }
        }
    }

所以,我尝试将 return 语句移出子函数,如下所示:

func saveObjectToParse(gameLocal: Game) -> Bool {
        let game = PFObject(className:"Game")
        game["sport"] = gameLocal.sport.rawValue
        var saved = false
        game.saveInBackgroundWithBlock {
            (success: Bool, error: NSError?) -> Void in
            if (success) {
                print("Object has been saved.")
                saved = true
            } else {
                print("parse error")
            }
        }
        return saved
    }

但是,这个 returns 在 saveInBackgroundWithBlock() 块执行之前保存,因为它是一个后台进程。因此,得救永远不会是真的,即使它本来是这样的。我尝试添加一个名为 done 的布尔标志,并尝试使用 while(!done) 循环等待,但这会冻结循环中的程序并且后台进程永远不会执行。我该如何解决这些问题?

从一个函数返回一个值但从另一个函数返回值在体系结构上没有意义。也不可能。

您要么需要更改实现并使两种方法独立,要么考虑使用信号量。

http://www.g8production.com/post/76942348764/wait-for-blocks-execution-using-a-dispatch

我同意不需要返回布尔值的重组,但如果你真的,真的需要这个设置,你可以同步保存你的对象(所以你的代码会等待)像这样,

do {
        try game.save()
    } catch {
        print(error)
    }

您正在尝试做的事情(创建一个辅助函数来包装 Parse 保存函数)非常有意义并且可以轻松完成。

您不需要使用信号量,您当然也不想同步执行操作。相反,使用 completion hander 让您知道保存何时完成。 For more information on completion handlers see this link

func saveObjectToParse(gameLocal: Game, completion: (gameSaved: Bool) -> Void) {
    let game = PFObject(className:"Game")
    game["sport"] = gameLocal.sport.rawValue
    game.saveInBackgroundWithBlock {
        (success: Bool, error: NSError?) -> Void in

        // Set the completion handler to be result of the Parse save operation
        completion(gameSaved: success)
    }
}

你可以像这样调用这个函数

saveObjectToParse(someGameObject) { (gameSaved: Bool) in
    if gameSaved {
        print("The game has been saved.")
    } else {
        print("Error while saving the game")
    }
}

使用此技术,您可以类似地通过您的函数传播 saveInBackgroundWithBlock 的整个回调,以便您可以在错误发生时进行检查。

编辑:您似乎也在使用自己的自定义 class 来表示 Game 对象。我建议查看 subclassing PFObject 以便您可以轻松直接地为您的 Parse classes 建模。 More details in the documentation