SwiftUI使用Firebase数据时ObservedObject意外销毁致底层HStack消失问题
问题原因
核心是@ObservedObject的生命周期管理不符合预期:
@ObservedObject仅负责监听对象的状态变化,不持有对象的生命周期。当TestView因为selectedItem状态变化触发重绘时,你在View内部初始化的Query和TestQuery实例都会被销毁重建。- 测试用的
TestQuery实例重建时,testList会在init阶段同步赋值完成,所以重建后列表瞬间恢复,无法感知到差异。 - 而Firebase的
Query实例重建时,queriedList初始为空,Firestore查询是异步操作,需要等待网络回调才会赋值,所以重建后会看到下层HStack直接变成空的,看起来就像被销毁了。
解决办法
将TestView中两个ObservableObject的属性包装器从@ObservedObject替换为@StateObject即可:
// 替换前 @ObservedObject var query = Query() @ObservedObject var testQuery = TestQuery() // 替换后 @StateObject var query = Query() @StateObject var testQuery = TestQuery()
@StateObject会由SwiftUI持有对象的生命周期,只要TestView没有被销毁,对象实例就不会被重复创建,已经加载好的queriedList数据、原有HStack的滚动位置都会被保留。
可选验证方式
你可以在Query类的init方法中添加打印日志,修改前你会发现每次选中条目触发上层视图展示时,init都会被调用,说明实例被重复创建;修改为@StateObject后init仅会在TestView第一次加载时调用一次。
内容的提问来源于stack exchange,提问作者TJMac
相关产品推荐
相关产品推荐

