gpt4 book ai didi

swift - CollectionView:scrollToItem、reloadData 和 Dispatch 队列

转载 作者:行者123 更新时间:2023-11-28 16:04:37 24 4
gpt4 key购买 nike

大家下午好

我遇到了一个关于我一直关注的聊天应用程序教程的令人沮丧的错误,我想补救(教程没有解决这个问题,因为我已经转换到 Swift 3/Xcode8)。让我尝试描述问题:

两个用户之间的聊天记录使用 Firebase 数据库来存储和检索他们之间的对话消息。我正在使用 collectionView 来显示对话。我想在聊天记录中实现一项功能,这样当用户选择要查看的对话时,它会滚动到最新/最后一条“消息”,以便用户轻松继续对话。

这里是聊天记录 Controller 当前的相关代码:

func observeMessages() {
guard let uid = FIRAuth.auth()?.currentUser?.uid, let toId = user?.id else {
return
}

let userMessagesRef = FIRDatabase.database().reference().child("user-messages").child(uid).child(toId)
userMessagesRef.observe(.childAdded, with: { (snapshot) in

let messageId = snapshot.key
let messagesRef = FIRDatabase.database().reference().child("messages").child(messageId)
messagesRef.observeSingleEvent(of: .value, with: { (snapshot) in

guard let dictionary = snapshot.value as? [String: AnyObject] else {
return
}

self.messages.append(Message(dictionary: dictionary))

DispatchQueue.main.async(execute: {
self.collectionView?.reloadData()

let indexPath = IndexPath(item: self.messages.count - 1, section: 0)

self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: true)
})

}, withCancel: nil)

}, withCancel: nil)
}

我遇到的问题是关于要滚动到 collectionView 的无效 indexPath。使用 print 语句,我发现 reloadData() 被调用了很多次,这只是我从调试控制台假设 indexPath 无法“更新”或“跟上”值。

我是 GCD 的新手(我只被告知 UI 的更新应该始终在主线程上完成),并且想知道我的问题的答案是否在于设置适当的同步/异步执行,或者串行/并发队列。

Ex//使用后台线程获取对话消息并更新 indexPath,同时主线程异步重新加载数据和 scrollsToItem。

我不确定,但如果有人可以阐明这一点,或者为我指明正确的方向,我将不胜感激。非常感谢。

最佳答案

如果你的collectionView基于

self.messages array, 

self.messages.append(Message(dictionary: dictionary)) 

也进入主线程。

用于主线程表(collectionView 或 tableView)的所有数据列表必须仅在主线程上进行管理。

关于swift - CollectionView:scrollToItem、reloadData 和 Dispatch 队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40478587/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com