为什么不能修改在闭包外部声明的变量? [英] Why can I not modify a variable declared outside a closure?

查看:56
本文介绍了为什么不能修改在闭包外部声明的变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每次测试代码时,都会向pickerUI返回一个空字符串,而不是学院名称.这是为什么?调试时,docData设置正确,但是在关闭后会变回空字符串.

Every time I test my code, an empty string is returned to the pickerUI rather than the college name. Why is that? When debugging, docData is set correctly but changes back to an empty string after the closure.

var ans = "";
var pickerData = [Any?]();
let db = Firestore.firestore();

override func viewDidLoad() {
    super.viewDidLoad();
    let docRef = db.collection("colleges").document("UMD");
    var docData = "";
    docRef.getDocument {  ( document, error) in
        if error == nil {
            docData = document!.get("Name") as! String;

        } else{

        }
    }
    pickerData.append(docData);
    picker.delegate = self
    picker.dataSource = self
}

推荐答案

这是因为数据是从Firestore异步加载的,因此您的主代码继续运行.通过放置一些日志语句最容易看到:

It's because data is loaded from Firestore asynchronously, and your main code continues to run while that is happening. It's easiest to see by placing a few log statements:

let docRef = db.collection("colleges").document("UMD")
print("Before starting to get data")
docRef.getDocument {  ( document, error) in
    print("Got data")
}
print("After starting to get data")

运行此代码时,它会打印:

When you run this code, it prints:

开始获取数据之前

Before starting to get data

开始获取数据后

获得数据

这可能不是您期望的顺序,但是它完全解释了为什么您的代码不起作用.到您的 pickerData.append(docData)运行时, docData = document!.get("Name")为!字符串尚未运行.

This is probably not the order you expected, but it does completely explain why your code doesn't work. By the time your pickerData.append(docData) runs, the docData = document!.get("Name") as! String hasn't run yet.

由于这个原因,任何需要从数据库中获取数据的代码都必须在闭包内部或从那里调用:

For this reason, any code that needs data from the database needs to be inside the closure, or be called from there:

let docRef = db.collection("colleges").document("UMD")
var docData = ""
docRef.getDocument {  ( document, error) in
    if error == nil {
        docData = document!.get("Name") as? String ?? "No Name"

        pickerData.append(docData)
        picker.delegate = self
        picker.dataSource = self
    } else{

    }
}

另请参阅:

  • Asign value of a Firestore document to a variable
  • Using Firestore DB, how can I break out of a for loop inside of a snapshot listener when a certain condition is met?, which also shows using a custom closure to keep your own code outside of the getDocument closure.
  • Storing asynchronous Cloud Firestore query results in Swift, showing using a dispatch group to keep the code

这篇关于为什么不能修改在闭包外部声明的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆