You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Firebase的onChildRemoved方法中删除UITableView对应单元格

解决Firebase删除数据后UITableView未更新的问题

看起来你遇到的问题是从Firebase删除用户关联的课程后,UITableView里的旧数据还没消失。核心问题有两个:一是你在childAdded里监听class_info用了.value事件(会重复触发导致数组重复添加),二是childRemoved里没正确找到要删除的数据并更新表格。我帮你一步步解决:

第一步:修正childAdded里的重复添加问题

你现在在获取class_id后,用observe(DataEventType.value)监听class_info,这会导致每次class_info的数据变化时都会执行闭包,重复把同一个Class对象添加到classes2数组里。应该换成observeSingleEvent(.value),这样只获取一次数据,避免重复:

Database.database().reference().child("Classes").child(class_id!)
.child("class_info").observeSingleEvent(of: .value, with: { (snapshot) in
    print("2.5",snapshot)
    let postDict = snapshot.value as? [String : AnyObject] ?? [:]
    print("3", postDict)
    let class_object = Class(dictionary: postDict)
    // 先判断数组里有没有这个class_id的对象,避免重复添加(可选但推荐)
    if !self.classes2.contains(where: { $0.class_id == class_object.class_id }) {
        self.classes2.append(class_object)
        DispatchQueue.main.async {
            self.tb_Yourclasses.reloadData()
        }
    }
}, withCancel: nil)

第二步:完善childRemoved的逻辑

当触发.childRemoved时,你拿到了被删除的class_id,接下来需要:

  1. 在classes2数组中找到对应class_id的元素
  2. 移除该元素
  3. 在主线程更新UITableView(用删除动画比直接reload更友好)

修改后的childRemoved闭包代码:

Database.database().reference().child("Users").child(userID).child("Classes").observe(.childRemoved, with: { (snapshot) in
    guard let deletedClassId = snapshot.value as? String else { return }
    
    // 找到数组中对应class_id的元素的索引
    if let index = self.classes2.firstIndex(where: { $0.class_id == deletedClassId }) {
        // 在主线程更新UI
        DispatchQueue.main.async {
            // 移除数组元素并删除表格单元格
            self.classes2.remove(at: index)
            self.tb_Yourclasses.deleteRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
        }
    }
})

额外注意点

  • 确保你的Class模型里的class_id属性正确映射自Firebase的uid字段(看你的数据库结构,class_info里的uid就是课程ID),这样才能匹配到要删除的元素。
  • 所有UI操作(比如更新表格)必须放在DispatchQueue.main.async里,因为Firebase的回调是在后台线程执行的。

修改后的完整fetchClass2函数

func fetchClass2(){
    guard let userID = Auth.auth().currentUser?.uid else { 
        print("用户未登录")
        return
    }
    print(userID)
    
    // 监听课程添加
    Database.database().reference().child("Users").child(userID).child("Classes").observe(.childAdded, with: { (snapshot) in
        print("1",snapshot)
        guard let class_id = snapshot.value as? String else { return }
        print("2",class_id)
        
        Database.database().reference().child("Classes").child(class_id).child("class_info").observeSingleEvent(of: .value, with: { (snapshot) in
            print("2.5",snapshot)
            let postDict = snapshot.value as? [String : AnyObject] ?? [:]
            print("3", postDict)
            let class_object = Class(dictionary: postDict)
            
            // 避免重复添加
            if !self.classes2.contains(where: { $0.class_id == class_object.class_id }) {
                self.classes2.append(class_object)
                DispatchQueue.main.async {
                    self.tb_Yourclasses.reloadData()
                }
            }
        }, withCancel: nil)
    }, withCancel: nil)
    
    // 监听课程删除
    Database.database().reference().child("Users").child(userID).child("Classes").observe(.childRemoved, with: { (snapshot) in
        guard let deletedClassId = snapshot.value as? String else { return }
        
        if let index = self.classes2.firstIndex(where: { $0.class_id == deletedClassId }) {
            DispatchQueue.main.async {
                self.classes2.remove(at: index)
                self.tb_Yourclasses.deleteRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
            }
        }
    })
}

这样修改后,当你从Firebase删除用户的课程关联时,UITableView会自动删除对应的单元格,而且不会有重复数据的问题。

内容的提问来源于stack exchange,提问作者Samuel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:30:30