SwiftUI中ObservableObject切换视图被重置为空的问题咨询
解决SwiftUI视图切换时数据重置的问题
你猜的完全没错!问题根源就是每次切换到allData视图时,@ObservedObject var datas = fetchDataModel()这行代码会重新创建一个fetchDataModel实例,之前加载的数据自然就被清空了。下面给你几个实用的解决办法:
1. 使用@StateObject替代@ObservedObject(推荐,iOS 14+)
从iOS 14和macOS 11开始,SwiftUI提供了@StateObject属性包装器,它会保证对象在视图的整个生命周期内只初始化一次,哪怕视图因为切换、重绘等原因被重建,实例也会被保留。
只需要修改allData视图里的属性声明:
struct allData: View { // 把@ObservedObject改成@StateObject @StateObject var datas = fetchDataModel() // ... 其余代码不变 }
这个方案最简单,适合你的数据只在allData视图里使用的场景。
2. 将模型提升到父级,用@EnvironmentObject共享
如果你的数据需要在多个视图(比如侧边菜单和allData)之间共享,或者希望模型的生命周期和整个App/父视图绑定,那就把模型的初始化放到更高层级,再通过环境传递给子视图。
步骤如下:
- 在父级视图(比如App入口、包含侧边菜单的根视图)中创建模型实例:
struct RootView: View { @StateObject var dataModel = fetchDataModel() var body: some View { // 侧边菜单逻辑... } }
- 把模型注入到环境中,让子视图可以访问:
struct RootView: View { @StateObject var dataModel = fetchDataModel() var body: some View { YourSideMenuView() .environmentObject(dataModel) // 注入环境 } }
- 在
allData视图中通过@EnvironmentObject接收模型:
struct allData: View { @EnvironmentObject var datas: fetchDataModel // 不需要自己初始化 // ... 其余代码不变 }
这样不管怎么切换视图,模型都是同一个实例,数据自然不会丢失。
3. 优化fetchData方法的加载逻辑
另外可以检查一下你的fetchData方法,如果每次调用都会先清空datas数组再重新加载,那即使实例保留了,每次切换回来也会重新刷新数据。如果不需要每次都重新加载,可以加个判断:
class fetchDataModel: ObservableObject { @Published var datas:[data] = [data]() func fetchData() { // 只有当数组为空时才加载数据 guard datas.isEmpty else { return } // 你的数据加载逻辑,比如网络请求、本地读取等 } }
这样第一次进入视图时加载数据,后续切换回来就不会重复加载,也不会清空现有数据。
内容的提问来源于stack exchange,提问作者Yann Massard
相关产品推荐
相关产品推荐

