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

在SwiftUI函数中使用@FetchRequest触发StateObject访问错误

问题解决:SwiftUI动态@FetchRequest导致的StateObject错误

错误原因

你把@FetchRequest放在函数内部使用是完全错误的——@FetchRequest这类属性包装器必须作为视图结构体的存储属性存在,放在函数里会导致SwiftUI无法正确管理其底层依赖的StateObject生命周期,从而触发Accessing StateObject's object without being installed on a View运行时错误。

同时你的代码还有两个潜在问题:

  • compartment属性设置了无意义的默认值= Compartment(),它应该由前一个视图传入,不需要默认值
  • 用compartment.name作为谓词匹配条件存在风险,Core Data中关联对象应该直接用对象引用而非属性值(避免名称重复导致数据错误)

正确实现代码

import SwiftUI
import CoreData

struct CompartmentDetailView: View {
    @Environment(\.managedObjectContext) private var viewContext
    let compartment: Compartment // 由前一个视图传入,无默认值
    
    // 动态初始化的@FetchRequest,关联当前compartment的库存
    @FetchRequest private var inventories: FetchedResults<Inventory>
    
    // 自定义初始化器,根据传入的compartment设置查询谓词
    init(compartment: Compartment) {
        self.compartment = compartment
        // 直接用compartment对象作为谓词条件,符合Core Data关联规范
        let predicate = NSPredicate(format: "compartment == %@", compartment)
        _inventories = FetchRequest(
            sortDescriptors: [NSSortDescriptor(keyPath: \Inventory.name, ascending: true)],
            predicate: predicate,
            animation: .default
        )
    }
    
    var body: some View {
        ScrollView {
            NavigationView {
                List {
                    ForEach(inventories) { inventory in
                        NavigationLink(
                            destination: InventoryDetailView(inventory: inventory)
                        ) {
                            HStack(spacing: 20.0) {
                                Text(inventory.name ?? "")
                                    .font(.headline)
                            }
                        }
                    }
                }
            }
        }
        .padding(.top, 30)
        .navigationTitle(compartment.name ?? "")
    }
}

关键说明

  1. @FetchRequest的正确位置:必须作为视图的存储属性,通过自定义初始化器动态传入谓词,SwiftUI会自动管理其生命周期和视图更新
  2. 谓词的正确写法:用compartment对象直接匹配而非name属性,既保证数据准确性,又符合Core Data对象关联的设计逻辑
  3. 处理可选值:Core Data实体的属性通常是可选类型,所以用?? ""处理name的nil情况,避免运行时崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:35:09