不确定如何在异步调用

时间:2017-12-27 17:19:35

标签: ios swift

我正在尝试使用observeSingleEvent从Firebase获取名为City的某些子节点,但我在尝试将其拉入主线程时遇到问题。我已经使用了完成处理程序和调度调用的组合,但我不确定我做错了什么,除了在异步的东西中没那么好。在viewDidLoad我试图从setupSavedLocations函数中追加我的密钥并将其返回savedLocations我觉得我很亲密。我错过了什么?

编辑:有问题的清晰度

import UIKit
import Firebase

class SavedLocationsViewController: UIViewController {

    var userID: String?
    var savedLocations: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        setupSavedLocations() { (savedData) in
            DispatchQueue.main.async(execute: {
                self.savedLocations = savedData
                print("inside", self.savedLocations)
            })
        }
        print("outside",savedLocations)
    }

        func setupSavedLocations(completion: @escaping ([String]) -> ()) {
        guard let user = userID else { return }
        let databaseRef = Database.database().reference(fromURL: "https://************/City")
        var dataTest : [String] = []
        databaseRef.observeSingleEvent(of: .value, with: {(snapshot) in
            let childString = "Users/" + user + "/City"
            for child in snapshot.children {
                let snap = child as! DataSnapshot
                let key = snap.key
                dataTest.append(key)
            }
            completion(dataTest)
        })
    }

示例输出

outside []
inside ["New York City", "San Francisco"]

1 个答案:

答案 0 :(得分:1)

setupSavedLocations的调用是异步的,运行时间比cpu完成viewDidLoad所需的时间长,这就是为什么没有显示数据的原因。您还可以从输出中注意到outsideinside之前调用class SavedLocationsViewController: UIViewController { var myActivityIndicator: UIActivityIndicatorView? override func viewDidLoad() { super.viewDidLoad() setupSavedLocations() { (savedData) in DispatchQueue.main.async(execute: { showSavedLocations(locations: savedData) }) } // We don't have any data here yet from the IO call // so we show the user an indicator that the call is // being made and they have to wait let myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray) myActivityIndicator.center = view.center myActivityIndicator.startAnimating() self.view.addSubview(myActivityIndicator) self.myActivityIndicator = myActivityIndicator } func showSavedLocations(locations: [String]) { // This function has now been called and the data is passed in. // Indicate to the user that the loading has finished by // removing the activity indicator myActivityIndicator?.stopAnimating() myActivityIndicator?.removeFromSuperview() // Now that we have the data you can do whatever you want with it here print("Show updated locations: \(locations)") } 。处理此方案的正确方法是向用户显示他们需要等待IO调用,然后在您拥有它时向他们显示相关信息。

SELECT first_assigned_to AS Designer, 
Count(DISTINCT CASE WHEN date_first_assigned_to >= YEAR(CURDATE()) THEN quote_email END) AS totalLeads 
FROM  quotes_new_assigned  
GROUP BY first_assigned_to;