【问题标题】:tableview.reloaddata() still works outside of Dispatchqueue.main.sync when we retrieve data from FireStore当我们从 FireStore 检索数据时,tableview.reloaddata() 在 Dispatchqueue.main.sync 之外仍然有效
【发布时间】:2021-09-21 12:47:03
【问题描述】:

规则是“如果您更新在另一个线程中工作的闭包内的用户界面,那么您应该调用 DispatchQueue.main.async 方法。但是,在我从 Firestore 检索数据后,tableview.reloadData () 在没有 DispatchQueue.main.async 方法的情况下仍然可以工作,并且它在闭包内的 MainThread 中工作。这怎么可能?有什么变化吗?Xcode 12.4 版;Swift 5 版

   func loadMessages(){
    messages = []
    
    db.collection(K.FStore.collectionName).getDocuments { (querySnapShot, error) in
        if let err = error {
            print("There was an issue retrieving data from Firestore. \(err)")
        }else{
            if let snapShotDocuments = querySnapShot?.documents{
                for doc in snapShotDocuments{
                    let data = doc.data()
                    if let messageSender = data[K.FStore.senderField] as? String,let messagebody = data[K.FStore.bodyField] as? String{
                        let newMessage = Message(sender: messageSender, body: messagebody)
                        self.messages.append(newMessage)
                    }
                }
            }
            if Thread.isMainThread{
                self.tableView.reloadData()
            }
        }
    }
}

【问题讨论】:

  • 调用时检查你所在的线程是什么。 Thread.isMainThread,或者使用断点...闭包可能会在main中调用...
  • 规则是“如果你在闭包内更新用户界面,那么你应该调用 DispatchQueue.main.async 方法——不。规则是“你应该在仅限主线程”
  • @Akif 你怎么知道的?你在控制台看到 Xcode 非主线程 ui 访问日志了吗?
  • @AndreyChernukha,你是对的,我已经检查过了,然后我明白我在 mainThread。
  • 让我们澄清一下:在闭包内部,并不能保证您是否在主线程中。因此,根据它的编码方式(如果需要,请参阅文档),您可以在主线程、调用方法的线程、“随机”后台线程等内部。

标签: ios google-cloud-firestore tableview dispatch-queue


【解决方案1】:

Firestore SDK(和大多数 Firebase SDK)在主线程上调用您的回调,正是为了让您可以轻松更新 UI。它们过渡到主线程,因此您不必这样做。

也可以在这里查看我的答案:

【讨论】:

    猜你喜欢
    • 2021-02-24
    • 1970-01-01
    • 2021-02-22
    • 2012-07-12
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多