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

时间:2018-06-14 13:36:43

标签: ios swift uitextview

抱歉新手在这里。我试图关注this stack overflow answer,但我失败了。我的猜测是getInfoFromDatabase{ (success) -> Void in if success { loadInfoOntoUI() } } 在数据库完成获取数据之前运行了吗?知道如何解决这个问题吗?

viewDidLoad代码:

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)
}

getInfoFromDatabase函数:

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)
}

loadInfoOntoUI函数:

{{1}}

非常感谢!

4 个答案:

答案 0 :(得分:0)

在观察区内召唤完成......

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)
     })
}

答案 1 :(得分:0)

这一行

completion(true)

应该完成正在运行的任务,以便在获取数据后返回它,对此更正

 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)
    })


}

答案 2 :(得分:0)

通过将完全处理程序置于异步块之外,您完全绕过了完成处理程序。

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

答案 3 :(得分:0)

你不应该使用那样的完成块。您的代码也可能会创建保留周期(如果不使用weak self,则从动作块到达UI元素是不安全的)。 考虑使用任何异步任务库,如PromiseKitBoltsSwift

https://github.com/mxcl/PromiseKit

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