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

SwiftUI报错:未找到MakeMyOwnListViewModel类型的ObservableObject

错误解决与ObservableObject/EnvironmentObject用法指南

错误原因

你遇到的No ObservableObject of type MakeMyOwnListViewModel found错误,核心是:使用@EnvironmentObject的View必须从祖先View的环境中获取对应ViewModel实例,但你的代码中,当从MainView导航到MakeMyOwnListView时,MainView所在的WindowGroup并没有注入MakeMyOwnListViewModel,导致子View找不到实例。

代码修正步骤

1. 修正App中的ViewModel声明与注入

在ManifestationMenuApp中,用@StateObject创建唯一的MakeMyOwnListViewModel实例,然后在所有需要的环境中注入这个实例(而不是每次新建):

import SwiftUI

@main
struct ManifestationMenuApp: App {
    
    @AppStorage("isOnboarding") var isOnboarding: Bool = true
    
    // 创建全局唯一的ViewModel实例,生命周期与App绑定
    @StateObject var listViewModel: MakeMyOwnListViewModel = MakeMyOwnListViewModel()
    
    var body: some Scene {
        WindowGroup {
            if isOnboarding {
                OnboardingView()
            } else {
                MainView()
                    .environmentObject(MenuListFriendshipViewModel())
                    .environmentObject(MenuListWealthViewModel())
                    .environmentObject(MenuListEducationViewModel())
                    .environmentObject(MenuListCareerViewModel())
                    .environmentObject(MenuListFamilyViewModel())
                    .environmentObject(MenuListHealthViewModel())
                    .environmentObject(MenuListSpiritualityViewModel())
                    // 注入共享的MakeMyOwnListViewModel到MainView环境
                    .environmentObject(listViewModel)
            }
        }
        
        WindowGroup {
            NavigationView {
                MakeMyOwnListView()
            }
            .navigationViewStyle(StackNavigationViewStyle())
            // 复用同一个实例,确保数据同步
            .environmentObject(listViewModel)
            
        }
    }
}

2. 保持MakeMyOwnListView的正确声明

MakeMyOwnListView中继续使用@EnvironmentObject,不要改成@ObservableObject——因为这个View是共享父级的ViewModel实例,而非自己创建:

struct MakeMyOwnListView: View {
    
    @EnvironmentObject var listViewModel: MakeMyOwnListViewModel
    
    // 其余代码保持不变
}

ObservableObject系列属性的核心用法

@ObservableObject

  • 用于标记遵循ObservableObject协议的类,在View中声明时,表示该View拥有这个ViewModel的独立实例。
  • 缺点:每个使用@ObservableObject的View会创建自己的实例,数据无法跨View共享;View销毁时,ViewModel也会被销毁。
  • 适用场景:仅当前View使用的ViewModel,不需要共享数据的情况。

@StateObject

  • SwiftUI 2.0+引入,用于在App/父View级别创建唯一且生命周期绑定的ViewModel实例。
  • 特点:实例只会被创建一次,宿主(App/View)存在时,实例不会被意外销毁,是实现全局/跨View共享数据的正确方式。
  • 适用场景:需要多个View共享数据的ViewModel,比如你的MakeMyOwnListViewModel。

@EnvironmentObject

  • 用于在子View中获取祖先View通过.environmentObject(_:)注入的ViewModel实例,无需手动传递参数。
  • 要求:必须在当前View的某个祖先View(包括App级的WindowGroup)上调用.environmentObject(_:)注入对应实例,否则会触发找不到实例的致命错误。
  • 适用场景:跨多层View共享同一个ViewModel实例的情况,比如从MainView跳转的MakeMyOwnListView、MakeMyOwnAddView等。

常见误区

  • 不要在每个需要ViewModel的View中用@ObservableObject创建实例,会导致数据割裂、实例重复。
  • 不要用@EnvironmentObject在App或父View中声明ViewModel,它只用于子View获取实例。
  • 注入environmentObject时,必须确保是同一个实例(比如用@StateObject创建的实例),否则多个窗口/View的数据无法同步。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 03:25:22