【问题标题】:Can't change the variable in the if-else , Swift [duplicate]无法更改 if-else 中的变量,Swift [重复]
【发布时间】:2019-12-19 11:12:01
【问题描述】:

我在我的 iOS 应用程序中使用 Firebase,并创建了一个函数,该函数从 Firestore 数据库返回一个值。问题是变量 val 在 if-else 构造后不会改变。

func getData(collection: String, doc: String, key: String) -> String {

    var val = "Simple string"

    var db: Firestore!
    let settings = FirestoreSettings()
    Firestore.firestore().settings = settings
    db = Firestore.firestore()

    let docRef = db.collection(collection).document(doc)
    docRef.getDocument { (document, error) in
        if let document = document, document.exists {
            val = (document.get(key) as! String)
            print(val)
        } else {
            val = "ERROR"
            print("Document does not exist")
        }
    }
    return val
}

这个函数必须返回来自 Firebase 的值(我可以通过 print(val) 看到它)但最后它返回初始值 简单字符串

我想我应该使用闭包来捕获 if-else 构造中的值,但我不知道该怎么做。

【问题讨论】:

  • 此函数必须返回值,因为getDocument 异步工作。您需要一个完成处理程序。几乎每周都会有人问这个问题。

标签: swift asynchronous


【解决方案1】:

将您的代码分为 3 部分,如下所示:

#1
docRef.getDocument { (document, error) in
    #2
}
#3

不能保证,但执行顺序可能是#1 -> #3 -> #2:

  • 初始化并调用getDocument#1
  • 返回val,即Simple String#3
  • 连接服务器,获取文档,调用#2

所以返回值将是Simple string。因为#2会异步执行。

正确的做法是:

func getData(
     collection: String,
     doc: String, 
     key: String,
     handler: @escaping (String) -> Void
   ) {

   #1 

   docRef.getDocument { (document, error) in ...

      if... else...

      callback(result)
   }
}

使用会像:

getData(collection: .., doc: .., key: ..) { val in
    print(val)
}

【讨论】:

    【解决方案2】:

    问题是块被异步执行,因此您的函数在响应块执行之前返回。我会建议改变你的函数的结构,像这样。

    func getData(fromCollection collection: String, doc: String, key: String, completion: @escaping (String?, Error?) -> Void) {
        var db: Firestore!
        let settings = FirestoreSettings()
        Firestore.firestore().settings = settings
        db = Firestore.firestore()
    
        let docRef = db.collection(collection).document(doc)
        docRef.getDocument { (document, error) in
            if let document = document,
                let val = document.get(key),
                document.exists {
                completion(val, nil)
            } else {
                completion(nil, error)
            }
        }
    }
    

    【讨论】:

    • 非常感谢!你能告诉我如何调用这个函数并返回一些值吗?
    猜你喜欢
    • 2021-11-22
    • 2016-11-22
    • 2019-02-25
    • 2021-12-28
    • 1970-01-01
    • 2017-04-26
    • 2022-01-10
    • 2018-07-10
    • 1970-01-01
    相关资源
    最近更新 更多