【问题标题】:How to return a value to a function while in background process subfunction in swift如何在swift的后台进程子函数中将值返回给函数
【发布时间】:2015-11-11 18:50:40
【问题描述】:

我首先尝试了这个解决方案,在我想要返回它的地方返回一个布尔值。但是,由于 parse.com 函数 saveInBackgroundWithBlock() 是一个 void 返回函数,我收到错误“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
    }

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

【问题讨论】:

  • 可能性包括让任何调用 saveObjectToParse 传入块以针对成功或失败情况执行或在保存完成时对通知做出反应。

标签: swift asynchronous parse-platform background-process


【解决方案1】:

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

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

【讨论】:

  • 我将 saveObjectToParse() 更改为 void 返回函数,并将根据 bool 的返回值执行的代码移动到函数本身。谢谢!
  • 应该真的,真的 推荐同步存档。 OP 只想围绕 Parse 保存函数创建一个简单的包装函数。这是正常的,可以使用 swift 中的完成块轻松实现
【解决方案2】:

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

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

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

【讨论】:

  • 是的,我期待答案更接近第二个代码块。我只是不确定如何确保在返回保存在较大函数中之前已完成其他函数。 while 循环策略不起作用,我之前从未做过任何异步操作。
  • 我认为您错过了 OP 的意图。在创建包装实用程序时传播异步操作的完成具有完美的架构意义
【解决方案3】:

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

您不需要使用信号量,当然也不想同步执行操作。相反,请使用完成处理程序让您知道保存何时完成。 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 的整个回调,以便在错误发生时检查它们。

编辑:看起来您还可以使用自己的自定义类来表示 Game 对象。我建议研究子类化PFObject,以便您可以轻松直接地为 Parse 类建模。 More details in the documentation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    相关资源
    最近更新 更多