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

SwiftUI新增第二个Environment Object时属性初始化报错如何解决

报错原因

  • 核心问题是类名和属性名完全重名:你定义的ObservableObject类命名为brandViewM,同时你在testApp中声明的@StateObject属性也命名为brandViewM。Swift编译器解析brandViewM()时,会优先匹配当前正在初始化的属性本身,而非同名类的构造函数,因此抛出两个报错:
    1. 无法在属性初始化阶段调用实例成员brandViewM,因此时self还未完成初始化
    2. brandViewM不是可调用的函数类型,无法添加()执行
  • 该问题和模型遵循Equatable还是Hashable没有关联,完全是命名冲突导致的编译错误。

解决方案

遵循Swift标准命名规范修改命名,避免重名即可:类名采用大驼峰命名,实例属性采用小驼峰命名。

步骤1:修改ObservableObject类命名

struct BrandItem:Codable, Equatable {
    var selectedText:String
    var brandUsername:String
    var brandPassword:String
}

// 类名改为大驼峰
class BrandViewModel: ObservableObject {
    @Published var branditems: [BrandItem] = [] {
        didSet {
            saveBrandItem()
        }
    }

    let branditemsKey:String = "branditemsKey"

    init() {
        getBrandItems()
    }

    func getBrandItems() {
        guard
            let data = UserDefaults.standard.data(forKey: branditemsKey),
            let savedDotItems = try? JSONDecoder().decode([BrandItem].self, from: data)
        else { return }
        
        self.branditems = savedDotItems
    }

    func deleteBrandItem(indexSet:IndexSet){
        branditems.remove(atOffsets: indexSet)
    }

    func addBrandItem(selectedText:String, brandUsername: String, brandPassword: String){
        let newBrandItem = BrandItem(selectedText: selectedText, brandUsername: brandUsername, brandPassword: brandPassword)
        branditems.append(newBrandItem)
        print(newBrandItem)
    }

    func saveBrandItem() {
        if let encodedData = try? JSONEncoder().encode(branditems) {
            UserDefaults.standard.set(encodedData, forKey: branditemsKey)
        }
    }
}

步骤2:修改入口处的属性声明与注入

@main
struct testApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    @StateObject var listViewModel: ListViewModel = ListViewModel()
    // 类型用修改后的大驼峰类名,属性用小驼峰命名
    @StateObject var brandViewModel: BrandViewModel = BrandViewModel()

    var body: some Scene {
        WindowGroup {
            NavigationView {
                ContentView()
                    .onAppear(){
                        UITableView.appearance().backgroundColor = .clear
                    }
            }
            .environmentObject(listViewModel)
            .environmentObject(brandViewModel)
        }
    }
}

步骤3:同步修改视图中的环境对象声明

// 同步修改类型为修改后的大驼峰类名
@EnvironmentObject var brandVM: BrandViewModel

如果不想修改原类名,也可以临时通过添加模块名前缀解决冲突:@StateObject var brandViewM:brandViewM = 你的App模块名.brandViewM(),但该方案不符合命名规范,不推荐长期使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:39:03