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

SwiftUI中如何基于父视图传入元素属性用NSPredicate过滤@FetchRequest?

解决SwiftUI中通过父视图属性过滤@FetchRequest的问题

问题场景

我有一组Core Data的Contract实体,每个Contract关联一组Invoice实体,且Contract拥有唯一的序列号属性。在Content View中通过@FetchRequest获取所有Contract生成列表,点击列表项通过NavigationLink跳转到子视图并传入对应的Contract实例。当前子视图无法实时显示新增的Invoice,只有返回Content View再重新进入才会刷新;尝试用传入的Contract序列号过滤@FetchRequest时,遇到报错:

Cannot use instance member 'aContract' within property initializer; property initializers run before 'self' is available

解决方案

方案1:直接利用Core Data关联关系(推荐)

既然已经传入完整的Contract实例,无需重新Fetch,直接使用其关联的Invoice集合即可。Core Data的关联关系默认支持动态更新,只要关联配置正确,新增Invoice后视图会自动刷新。

代码示例:

struct InvoiceDetailView: View {
    // 用@ObservedObject监听Contract实例的变化
    @ObservedObject var contract: Contract
    
    var body: some View {
        List {
            // 将Core Data的NSSet关联属性转为数组遍历
            ForEach(contract.invoiceArray?.allObjects as? [Invoice] ?? []) { invoice in
                Text(invoice.invoiceIdentificationAttribute ?? "无编号")
            }
        }
        .navigationTitle(contract.contractSerialNumber ?? "合同详情")
    }
}

注意:需确保Core Data中Contract与Invoice的关联关系配置正确,invoiceArray是Contract实体对应的To-Many关联属性(Xcode自动生成的类中默认是NSSet?类型,需转成数组使用)。

方案2:动态初始化@FetchRequest(适用于需要重新过滤的场景)

如果必须通过传入的属性动态创建@FetchRequest,可以通过初始化方法设置predicate,避开属性初始化时无法访问self的限制。

代码示例:

struct ContractInvoiceView: View {
    let contractSerialNumber: String
    @FetchRequest var contracts: FetchedResults<Contract>
    
    // 在初始化方法中动态配置FetchRequest
    init(contractSerialNumber: String) {
        self.contractSerialNumber = contractSerialNumber
        _contracts = FetchRequest(
            sortDescriptors: [],
            predicate: NSPredicate(format: "contractSerialNumber == %@", contractSerialNumber)
        )
    }
    
    var body: some View {
        List {
            // 利用唯一序列号取第一个匹配的Contract
            if let contract = contracts.first {
                ForEach(contract.invoiceArray?.allObjects as? [Invoice] ?? []) { invoice in
                    Text(invoice.invoiceIdentificationAttribute ?? "无编号")
                }
            }
        }
        .navigationTitle("发票列表")
    }
}

内容的提问来源于stack exchange,提问作者Andrei M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:31:02