使用Firebase observe函数时仅调用一次reloadTableView()的方法
解决只调用一次
reloadData()的问题 看起来你现在的困扰是每次给posts数组赋值时,didSet都会触发reloadData(),如果数据更新频繁或者赋值逻辑重复,就会导致多次不必要的刷新。要实现只调用一次刷新,我们可以从这几个关键点调整:
1. 提前处理数组顺序,剥离didSet里的额外操作
把posts.reverse()的逻辑从didSet中移到fetchData方法里,在生成临时数组foundPosts之后就完成反转。这样赋值给posts时就不需要再修改数组,既减少了重复操作,也避免didSet每次都执行反转逻辑。
2. 确保对posts只做一次赋值
在fetchData中,等遍历快照生成完整的foundPosts数组后,再一次性赋值给posts。这样didSet只会被触发一次,自然也就只调用一次reloadData()。
另外,如果你只是想首次加载数据时刷新一次,而非监听实时数据变化,记得把observe(.value)换成observeSingleEvent(.value)——Firebase只会获取一次数据,不会因为后续数据变动重复触发刷新。
修改后的代码示例:
var posts = [Post]() { didSet { // 仅保留刷新逻辑,移除reverse操作 self.tableView.reloadData() } } func fetchData(){ // 如需实时监听则换回observe(.value),仅首次加载用observeSingleEvent currentQuery.observeSingleEvent(.value, with: { (snapshot) in guard let snapshotArray = snapshot.children.allObjects as? [DataSnapshot] else { // 处理快照转换失败的情况 return } var foundPosts = [Post]() for snap in snapshotArray { if let postDict = snap.value as? Dictionary<String, Any>{ let key = snap.key let post = Post.init(postKey: key, postData: postDict) // 补全你的初始化参数 foundPosts.append(post) } } // 赋值前完成数组反转 foundPosts.reverse() // 一次性赋值,触发一次didSet self.posts = foundPosts }) }
额外补充:
如果确实需要监听实时数据变化(数据更新时自动刷新),那还是要用observe(.value),但每次数据变动仍会触发一次reloadData(),这是正常的实时更新逻辑。要是觉得全量刷新太频繁,可以考虑用Firebase的childAdded/childChanged等事件做局部刷新,而非每次都刷新整个tableView。
内容的提问来源于stack exchange,提问作者MrrOak
相关产品推荐
相关产品推荐

