swift 完成块没有按顺序执行任务?

swift completion block does not execute tasks in order?

对不起这里的新手。我试图关注 但我失败了。我的猜测是 completion(true) 在数据库完成获取数据之前是 运行?知道如何解决这个问题吗?

viewDidLoad 代码:

getInfoFromDatabase{ (success) -> Void in
        if success {
            loadInfoOntoUI()
        }
    }

getInfoFromDatabase 函数:

func getInfoFromDatabase(completion: (_ success: Bool) -> Void) {
    stoRef.observe(.value, with: { snapshot in
     self.caption = (snapshot.value as? NSDictionary)?["Caption"] as! String
     self.views = (snapshot.value as? NSDictionary)?["Views"] as! Int
     self.votes = (snapshot.value as? NSDictionary)?["Votes"] as! Int

     print(self.views)
     print(self.votes)
     print(self.caption)
    // these variables get printed correctly in console
    })

    completion(true)
}

loadInfoOntoUI 函数:

func loadInfoOntoUI() {
    captionText.text = self.caption
    print(self.caption) // But when I added a breakpoint here, the console says text is nil
    viewText.text = String(views)
    voteText.text = String(votes)
}

非常感谢!

在观察块内调用完成...

func getInfoFromDatabase(completion: (_ success: Bool) -> Void) {
    stoRef.observe(.value, with: { snapshot in
     self.caption = (snapshot.value as? NSDictionary)?["Caption"] as! String
     self.views = (snapshot.value as? NSDictionary)?["Views"] as! Int
     self.votes = (snapshot.value as? NSDictionary)?["Votes"] as! Int

     print(self.views)
     print(self.votes)
     print(self.caption)
     // these variables get printed correctly in console
     completion(true)
     })
}

这一行

completion(true)

应该是在完成运行任务后才能在获取数据后return,更正为这个

 func getInfoFromDatabase(completion: (_ success: Bool) -> Void) {
    stoRef.observe(.value, with: { snapshot in
     self.caption = (snapshot.value as? NSDictionary)?["Caption"] as! String
     self.views = (snapshot.value as? NSDictionary)?["Views"] as! Int
     self.votes = (snapshot.value as? NSDictionary)?["Votes"] as! Int

     print(self.views)
     print(self.votes)
     print(self.caption)
    // these variables get printed correctly in console
      completion(true)
    })


}

您将完成处理程序放在异步块之外,从而完全绕过了它。

stoRef.observe(.value, with: { snapshot in }

是一个异步函数,需要一些时间才能完成。您使用完成处理程序来告诉您它何时完成,因此您需要在异步完成处理程序中调用它。

stoRef.observe(.value, with: { snapshot in 
    // do stuff

    completion(true)
}

您的代码中发生了什么...

stoRef.observe(.value, with: { snapshot in // this gets called 1st
    // do stuff
    // this 3rd
}

completion(true) // this 2nd

你不应该那样使用完成块。您的代码也可能会创建保留循环(如果不使用 weak self,从操作块中获取 UI 元素是不安全的)。 考虑使用任何异步任务库,如 PromiseKitBoltsSwift:

https://github.com/mxcl/PromiseKit

https://github.com/BoltsFramework/Bolts-Swift