如何将 @FetchRequest 属性包装器的新 nsPredicate 动态属性与传递给 View 的对象一起使用

Posted

技术标签:

【中文标题】如何将 @FetchRequest 属性包装器的新 nsPredicate 动态属性与传递给 View 的对象一起使用【英文标题】:How to use the new nsPredicate dynamic property of @FetchRequest property wrapper with object passed into View 【发布时间】:2021-07-19 22:48:04 【问题描述】:

我的第一次尝试是在.onAppear 中设置属性包装器的nsPredicate 动态属性,但如果视图因任何原因重新初始化,.onAppear 设置的谓词将丢失。所以我又回到了使用初始化模式。

这是我认为应该有效(但没有)和有效(但神秘)的东西:

struct ItemEditView : View 
    
    var item: Item
    
    @FetchRequest(fetchRequest: Attribute.fetchRequestAllInOrder(), animation: .default)
    var attributes: FetchedResults<Attribute>

    init(item: Item) 
        self.item = item
        
        // This is how I would have expected to set the dynamic property at View initialization, however
        // it crashes on this statement
        attributes.nsPredicate = NSPredicate(format: "item == %@", item)
        
        // Not sure why the below works and the above does not.
        // It seems to work as desired, however it receives this runtime warning:
        // "Context in environment is not connected to a persistent store coordinator"
        $attributes.projectedValue.wrappedValue.nsPredicate = NSPredicate(format: "item == %@", item)
    
    
    var body: some View 
        List 
            ForEach(attributes)  attribute in
                Text("Name:\(attribute.name) Order:\(attribute.order)")
            
        
    

那么,为什么第一个赋值给 nsPredicate 会崩溃?在注释掉第一个之后,为什么第二个有效?警告信息是一个真正的问题吗?有一个更好的方法吗?似乎应该有一种使用新动态属性的简单方法来执行此操作。

【问题讨论】:

你为什么要获取item?只需包装传递的值@ObservedObject var item: Item 崩溃时的错误信息是什么? 崩溃是:线程1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) 抱歉,物品太多...实际上,我不是在取物品。我正在获取与传递到视图中的项目相关的所有属性。 Attribute 实体与名为“item”的 Item 实体有关系。 难道你没有从 Item 到 Attribute 的反向关系,因为那样你就不需要 fetch 请求。您的列表将类似于 ForEach(item.attributes) attribute in 假设反向关系的名称是 attributes 【参考方案1】:

事实证明,在onAppear 中(重新)设置@FetchRequestnsPredicate 属性确实是可行的方法。但是,要使这项工作正常进行,您必须确保在调用 onAppear 后不会再次调用 View 的 init() 方法。在今年的 WWDC (WWDC21-10022) 的 Demystify SwiftUI 会议中,有一些关于如何完成此任务的宝贵提示。

【讨论】:

Bring CoreData concurrency 使用自定义绑定 ***.com/questions/68530633/…

以上是关于如何将 @FetchRequest 属性包装器的新 nsPredicate 动态属性与传递给 View 的对象一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何定义协议以包含带有 @Published 属性包装器的属性

将绑定传递给类型属性包装器的变量 - 失去基础类型

Swift | 属性包装器

在 UUID 类型属性上使用 @FetchRequest 谓词过滤进行不可靠更新?

如何将 OpenCV 的 MatExpr 的 C 包装器的指针输出转换回 MatExpr

如何修复错误:@FetchRequest 中的“属性初始化程序在”自我“可用”之前运行