iOS Swift中UITableView无法正确刷新:最后一条数据未移除
问题分析与解决方案
看起来你遇到的问题核心在于数据更新后的UI刷新逻辑不完整,当最后一条问题被回答后,云端数据已经变为空,但本地的列表没有及时更新。让我一步步帮你解决:
1. 找到问题根源
你的fetchQues()方法里,只有当snapshot.childrenCount > 0时才会更新quesList并刷新表格。当最后一条问题被回答后,云端返回的snapshot没有子节点(childrenCount = 0),这个判断条件不成立,导致:
- 旧的
quesList数据没有被清空 - 表格也没有执行
reloadData()
所以返回列表页时,依然显示之前的那条数据。
2. 修复核心逻辑
修改fetchQues(),移除childrenCount的判断包裹,不管有没有数据都要更新列表并刷新UI:
func fetchQues(){ Ref.queryOrdered(byChild: currentuser).queryEqual(toValue: nil).observe(DataEventType.value, with:{(snapshot)in // 先清空旧数据,确保本地数据和云端一致 self.quesList.removeAll() if snapshot.childrenCount > 0 { for data in snapshot.children.allObjects as![DataSnapshot]{ // 建议用可选绑定替代强制解包,避免崩溃 guard let dataObject = data.value as? [String: AnyObject], let questionid = dataObject["id"] as? String, let userid = dataObject["sender_id"] as? String, let username = dataObject["sender_name"] as? String, let questext = dataObject["text"] as? String else { continue } let question = Question(id: questionid, sender_id: userid, sender_name: username, text: questext) self.quesList.insert(question, at: 0) } } // 不管有没有数据,都刷新表格 self.AnswerTable.reloadData() }) }
3. 优化监听生命周期(避免重复监听和内存泄漏)
因为你用的是observe(.value)持续监听,建议在视图控制器的生命周期方法中管理监听:
// 保存监听的句柄,方便后续移除 private var quesListener: DatabaseHandle? override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 每次页面出现时重新监听数据 fetchQues() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 页面消失时移除监听,避免重复监听和内存泄漏 if let listener = quesListener { Ref.removeObserver(withHandle: listener) } } func fetchQues(){ // 先移除之前的监听(如果存在) if let listener = quesListener { Ref.removeObserver(withHandle: listener) } quesListener = Ref.queryOrdered(byChild: currentuser).queryEqual(toValue: nil).observe(DataEventType.value, with:{(snapshot)in self.quesList.removeAll() if snapshot.childrenCount > 0 { for data in snapshot.children.allObjects as![DataSnapshot]{ guard let dataObject = data.value as? [String: AnyObject], let questionid = dataObject["id"] as? String, let userid = dataObject["sender_id"] as? String, let username = dataObject["sender_name"] as? String, let questext = dataObject["text"] as? String else { continue } let question = Question(id: questionid, sender_id: userid, sender_name: username, text: questext) self.quesList.insert(question, at: 0) } } self.AnswerTable.reloadData() }) }
4. 确认云端数据更新正确
检查DBProvider.Instance.postAnswered()方法,确保它确实给对应的问题添加了currentuser字段的值(不再是nil)。你可以在这个方法里添加打印日志,或者在Firebase控制台查看数据是否被正确更新。
为什么重新登录后正常?
重新登录时,fetchQues()会重新执行,此时云端数据为空,虽然之前的判断不成立,但修改后的代码会先清空quesList再刷新表格,所以列表会正确显示为空。
内容的提问来源于stack exchange,提问作者frankcrest
相关产品推荐
相关产品推荐

