Swift closure not setting variable

核能气质少年 提交于 2019-12-17 22:04:57

问题


I'm trying to set a variable that is outside a closure inside that closure, but it doesn't end up getting set in the end. However, the value that I'm setting the variable to is being printed to the console. Also, right after setting the return variable and printing it itself, the correct value is being printed to the console. The problem arises when I return the variable; its value stays the same as the value at initialization. Here is some psuedo-code:

let str: String = {
    var ret: String = "default value"

    functionWithClosure(with: (some_name) in {
        if let name = some_name {
            ret = name
            print(name) // prints successfully
            print(ret_name) // also prints successfully
        }
    })

    return ret // returns "default value"
}()

This is the actual code that isn't working:

let name: String = {
    var ret_name = "default value"

    if let uid = FIRAuth.auth()?.currentUser?.uid {
        FIRDatabase.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
            if let dictionary = snapshot.value as? [String: AnyObject] {
                if let name = dictionary["name"] as? String {
                    ret_name = name
                    print(ret_name)
                }
            }
        })
    }

    return ret_name
}()

回答1:


.observeSingleEvent is working async.

You can do something like this:

func getRetname(completion: @escaping(_ retName: String) -> Void) {
    if let uid = FIRAuth.auth()?.currentUser?.uid {
        FIRDatabase.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
        if let dictionary = snapshot.value as? [String: AnyObject] {
            if let name = dictionary["name"] as? String {
                ret_name = name
                print(ret_name)
                completion(ret_name)
            }
        }
    })
}

Then, you can use it everywhere you want:

getRetname(completion: { ret_name in 
    // ret_name - your data
})

Hope it helps




回答2:


May be below can be the workout for the issue.

func getName(completion: @escaping(_ name: String) -> Void) {
if let uid = FIRAuth.auth()?.currentUser?.uid {
    FIRDatabase.database().reference().child("users")
    .child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
    if let dictionary = snapshot.value as? [String: AnyObject] {
        if let name = dictionary["name"] as? String {
            completion(name)
        }
    }
})
}

Now set the value of string by below code

getName(completion: { name in 
     let str = name
 })


来源:https://stackoverflow.com/questions/43534111/swift-closure-not-setting-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!