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

SwiftUI中如何在不同模型之间共享数据?

报错原因

Swift 结构体初始化有严格的安全检查规则:所有存储属性必须在访问self的任何属性或方法之前完成赋值。你的代码中@EnvironmentObject修饰的user属于HomeView的实例属性,你在init方法中访问user的时候,alerts还没有完成初始化,自然就触发了'self' used before all stored properties are initialized的报错。

推荐解决方案

方案1:拆分Alerts的初始化和数据请求逻辑(最符合SwiftUI设计规范)

把Alerts的实例初始化和网络请求逻辑拆分,不需要修改现有视图层级:

  1. 给Alerts添加无参默认初始化方法,把拉取服务端数据的逻辑封装为单独的fetchData(userId:)方法
  2. 把alerts改为@StateObject(iOS 14+推荐,视图内部持有的可观察对象用@StateObject可以避免视图刷新时重复初始化的问题)
  3. 在HomeView的onAppear回调中判断user.id是否存在,存在则调用alerts的拉取方法
    代码示例:
struct HomeView: View {
    @EnvironmentObject var user: User
    // 先完成空初始化,满足Swift的初始化规则
    @StateObject var alerts = Alerts()
        
    var body: some View {
        // 你的HomeView原有布局代码
        VStack {
            // 展示提醒列表等逻辑
        }
        .onAppear {
            guard let userId = user.id else { return }
            alerts.fetchData(userId: userId)
        }
    }
}

// Alerts模型修改示例
class Alerts: ObservableObject {
    @Published var alertList: [AlertItem] = []
    
    func fetchData(userId: String) {
        // 原有请求逻辑挪到此处,用传入的userId发起网络请求
    }
}

方案2:父视图提前初始化Alerts传入

在跳转进入HomeView的父视图中,用户已经登录、user.id已经存在的时机,提前初始化Alerts实例,作为参数直接传入HomeView:
父视图跳转逻辑示例:

// 父视图中已经持有user的EnvironmentObject
if user.isLoginValid {
    // 提前初始化Alerts传入
    HomeView(alerts: Alerts(userId: user.id!))
        .environmentObject(user)
}

HomeView代码可以直接简化,不需要自定义初始化方法:

struct HomeView: View {
    @EnvironmentObject var user: User
    @ObservedObject var alerts: Alerts
    
    // 直接使用Swift自动生成的构造器即可
}

方案3:将Alerts也升级为全局共享对象

如果Alerts的数据需要在多个视图中复用,可以直接把Alerts也设置为EnvironmentObject,在用户登录完成、拿到userId的时机完成Alerts的初始化,注入到整个视图树中,后续所有视图都可以直接读取使用,不需要在HomeView单独处理。

关于嵌套视图方案的说明

你找到的嵌套视图方案不属于违规实现,本质是利用body闭包执行时、视图已经完全初始化、环境变量已经加载完成的时机传参初始化子视图,但是如果Alerts仅在HomeView中使用,上面三个方案的代码可读性和维护性会更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 18:15:05