Swift没有在return语句中设置值

时间:2017-04-09 18:56:34

标签: swift return

我有一个问题,在我看来不应该是一个问题。

当我加载这个'简单'功能,它应该返回数据库中的用户。

 - returns usersDictionary: All the users in a dictionary
*/
func getAllUsers() -> Dictionary<String, AnyObject> {
     var usersDict = Dictionary<String, AnyObject>()

    if userIsLoggedIn() == true{
        FIRDatabase.database().reference().child("users").observeSingleEvent(of: .value, with: { (snapshot) in
            if let userDictionary = snapshot.value as? [String:AnyObject]{
                for user in userDictionary{

                    usersDict.updateValue(user.value as AnyObject
                        , forKey: user.key as String)


                }
                print("TEST")
                print(usersDict)
            }
            print("TEST2")
            print(usersDict)
        })
        print("TEST3")
        print(usersDict)
        return usersDict

    }
    return usersDict
}

然而,它不会返回带有值的usersDict,但只是为空,这很奇怪,因为它打印出TEST和TEST2 usersDict的值。

但Test3仍然是空的,这怎么可能?如果我查看控制台,它首先执行Test3然后测试然后测试2.

这是控制台打印的内容:

TEST3
[:]
TEST
"ZuUiTSu142P5NTc9VfekRbuFcny2": {
    address = "testAddress";
    email = "test@outlook.com";
    name = "testuser";
    phonenumber = "1234567890";
    rol = Customer;
}]
TEST2
"ZuUiTSu142P5NTc9VfekRbuFcny2": {
    address = " testAddress ";
    email = " test@outlook.com ";
    name = "testuser";
    phonenumber = "1234567890";
    rol = Customer;
}]

2 个答案:

答案 0 :(得分:0)

@vadian正确地发表了他的评论:在异步获取数据时,您正试图同步返回函数中的值。您// lines of code在这里发生的一切:

FIRDatabase.database().reference().child("users").observeSingleEvent(of: .value, with: { (snapshot) in
  // ...
  // lines of code
  // ...
})

异步发生。含义:它发生在后台,并且首先执行observeSingleEvent调用后的任何代码,因此您将TEST3视为第一行输出。

围绕Asynchronous Model设计代码有几种不同的方法。可能最简单的方法是在Async代码完成执行后传递一个Callback函数。

听起来很混乱?别担心,一开始会让人感到困惑,但是一旦你得到它,你会惊讶于它的概念有多么简单。

我不打算解释Callbacks和Async是如何工作的,但是我会指向一个有很好答案的similar problem。看看它,你应该明白这一点。

祝你好运!

答案 1 :(得分:0)

谢谢大家的答案,也许有点太晚了,因为我暂时跳过这部分并专注于其他事情,但我今天看了它并设法做到最后很容易。

 func loadBusiness(busUID: String,with completion: @escaping(_ business: [String:AnyObject], _ error: NSError?) -> Void){
        FIRDatabase.database().reference().child("businesses").child(busUID).observeSingleEvent(of: .value, with: { (snapshot) in
            if let busDict = snapshot.value as? [String:AnyObject]{
                completion(busDict, nil)
            }
        }) { (error) in
            print("Error occured: " + error.localizedDescription)
        }
    }

只是一个关于我如何设法做到这一点的简单示例,我现在可以随处调用它:

// Load basic company info
        db.loadBusiness(busUID: db.getMyUID()) { (business, error) in
            self.myCompany = business
        }