为什么不能修改在闭包外部声明的变量?

问题描述 投票:-1回答:1

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

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
}
swift firebase google-cloud-firestore closures swift4
1个回答
0
投票

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

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

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

开始获取数据之前

开始获取数据后

获取数据

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

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

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

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

    }
}

另请参阅:

© www.soinside.com 2019 - 2024. All rights reserved.