【问题标题】:Swift closure not setting variableSwift 闭包未设置变量
【发布时间】:2017-09-17 22:46:14
【问题描述】:

我正在尝试在该闭包内设置一个位于该闭包之外的变量,但它最终并没有被设置。但是,我将变量设置为 的值正在打印到控制台。此外,在设置返回变量并自行打印之后,正确的值将被打印到控制台。当我返回变量时出现问题;它的值与初始化时的值相同。这是一些伪代码:

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

这是不起作用的实际代码:

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

【问题讨论】:

  • 请提及您遇到的错误以及它是编译时错误还是运行时错误。
  • 我没有收到错误消息。问题是ret 在返回时保持为“默认值”。
  • 如果您也提供关闭代码会更有帮助。functionWithClosure 您正在使用。
  • 我添加了更具体的代码。
  • 您的闭包方法是一个异步方法,因此在您的闭包完成执行之前调用 return。您可以通过调试代码在return 行和print(ret_name) 行上放置断点来检查它,return 将首先被调用。这就是它返回默认值的原因。

标签: swift firebase firebase-realtime-database closures firebase-authentication


【解决方案1】:

.observeSingleEvent 正在异步工作。

你可以这样做:

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

然后,你可以在任何你想要的地方使用它:

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

希望对你有帮助

【讨论】:

  • 如何让另一个函数返回ret_name的值?
  • @ArchieGertsman 你是什么意思?您现在可以像我在下面写的那样使用 getRetname。 ret_name 现在是您的打印值
【解决方案2】:

下面可能是解决问题的方法。

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

现在通过下面的代码设置字符串的值

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

【讨论】:

  • mm,查看其他答案:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多