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

为什么向数组追加值后返回null或为空?Firebase数据加载问题求解

问题原因及解决方案

核心问题原因

Firebase Realtime Database 的 observe(_:with:) 是异步网络请求操作,不会阻塞当前主线程执行,你的代码执行顺序和你预想的完全不同:

  1. 调用 createArray() 时,先执行到 taskRef?.observe(...) 这一行,只是向Firebase注册了一个数据监听回调,回调不会立刻执行
  2. 主线程不会等待网络请求返回,直接继续往下走,执行 print("outside of observe func --> ", taskTitles),此时数组还是空的,然后就把空数组返回给了 viewDidLoad 里的 taskTitles
  3. 等后续网络请求成功拿到Firebase返回的数据后,你注册的闭包回调才会执行,把数据追加到taskTitles数组里,但此时你没有通知UITableView刷新数据,所以界面上也看不到新数据

修复方案

1. 调整方法逻辑,去掉同步返回

createArray 不需要返回数组,异步操作无法同步返回请求结果,修改方法返回值为Void:

func createArray() {
    taskRef = Database.database().reference(withPath: "Tasks")
    refHandle = taskRef?.observe(DataEventType.value, with: { [weak self] snapshot in
        guard let self = self else { return }
        // 可选:先清空旧数据,避免监听触发多次导致数据重复
        self.taskTitles.removeAll()
        for taskSnapshot in snapshot.children {
            let nodeA = taskSnapshot as! DataSnapshot
            let keyA = nodeA.key
            let theTask = Task(title: String(keyA))
            self.taskTitles.append(theTask)
        }
        // 所有数据处理完成后,切回主线程刷新列表
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    })
}

2. 修改viewDidLoad调用逻辑

不需要接收返回值,直接调用方法即可:

override func viewDidLoad() {
    super.viewDidLoad()
    title = "To Do List"
    configureNavigationItems()
    // 直接调用,不需要赋值
    createArray()
    
    tableView.delegate = self
    tableView.dataSource = self
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:24:05