为什么向数组追加值后返回null或为空?Firebase数据加载问题求解
问题原因及解决方案
核心问题原因
Firebase Realtime Database 的 observe(_:with:) 是异步网络请求操作,不会阻塞当前主线程执行,你的代码执行顺序和你预想的完全不同:
- 调用
createArray()时,先执行到taskRef?.observe(...)这一行,只是向Firebase注册了一个数据监听回调,回调不会立刻执行 - 主线程不会等待网络请求返回,直接继续往下走,执行
print("outside of observe func --> ", taskTitles),此时数组还是空的,然后就把空数组返回给了viewDidLoad里的taskTitles - 等后续网络请求成功拿到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
相关产品推荐
相关产品推荐

