【发布时间】: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