带有 NSPredicate 的 FetchRequest 不会在新条目上更新

Posted

技术标签:

【中文标题】带有 NSPredicate 的 FetchRequest 不会在新条目上更新【英文标题】:FetchRequest with NSPredicate does not update on new entries 【发布时间】:2020-05-02 10:19:02 【问题描述】:

我正在试验 SwiftUI 和 CoreData。 在 ListView 中,我通过 FetchRequest 显示具有给定谓词的所有条目:

struct MyList: View 
    var task: Task

    @FetchRequest
    var events: FetchedResults<Event>

    @Environment(\.managedObjectContext)
    var viewContext

    init(task: Task) 
        self.task = task
        self._events = FetchRequest(entity: Event.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Event.timestamp, ascending: true)],
                                    predicate: NSPredicate(format: "%K == %@", #keyPath(Event.task), task.id.uuidString), animation: .default)
    

    var body: some View 
        VStack 
            EditButton()
            List 
                ForEach(self.events, id: \.self)  event in
                    Text("\(event.someProperty)")
                
            .onDelete  indices in
                self.events.delete(at: indices, from: self.viewContext)
            
        
        .navigationBarItems(
             trailing: Button(
                 action: 
                     withAnimation 
                         Event.create(for: self.task, in: self.viewContext)
                     
                 
              ) 
                  Image(systemName: "plus")
              
        )
    


extension Event 
    static func create(for task: Task, in managedObjectContext: NSManagedObjectContext)
        let newEvent = self.init(context: managedObjectContext)
        newEvent.task = task.id
        newEvent.timestamp = Date()

        do 
            try  managedObjectContext.save()
         catch 
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        
       


extension Collection where Element == Event, Index == Int 
    func delete(at indices: IndexSet, from managedObjectContext: NSManagedObjectContext) 
        indices.forEach  managedObjectContext.delete(self[$0])        

        do 
            try managedObjectContext.save()
         catch 
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        
    

一切正常。如果我删除一个条目,它会自动从列表中消失。

但如果我添加一个条目,它只会在应用重启后添加到列表中。如果我删除 NSPredicate 新条目会立即显示。这是一个错误还是我错过了什么?感谢您的帮助。

【问题讨论】:

你在Event.create做什么? 我为Event添加了扩展码 大概 Task.id 是一个 UUID。您设置 newEvent.task = task.id,但您的谓词指定 task == task.id.uuidString。我的猜测是,在获取过程中,CoreData 成功地将 UUID 与其等效的字符串桥接,但上下文的内存处理却没有。如果使用 task == task.id 作为谓词,效果会更好吗? pbasdf 你搞定了。比较 UUID 更有意义。我对Argument type 'UUID' does not conform to expected type 'CVarArg' 错误感到困惑。但是对 CVarArg 进行强制转换后一切正常。谢谢! 【参考方案1】:

有pbasdf 指出问题确实是与NSPredicate 中的UUID 比较。在比较 UUID 而不是字符串后,一切都按预期工作。

将 UUID 与给定的字符串进行比较可以获取初始数据。可能它已在数据库中正确处理,但不适用于“内存中”处理。例如

NSPredicate(format: "%K == %@", #keyPath(Event.task), task.id.uuidString)

适用于删除操作,但不适用于插入新条目。

要解决此问题,谓词应如下所示

NSPredicate(format: "%K == %@", #keyPath(Event.task), task.id as CVarArg)

另见: https://jisyed.github.io/blog/2018/using-uuids-in-predicates-to-fetch-core-data-entities/

【讨论】:

一年后我发现我的问题与这个很好的答案谢谢谢谢谢谢你非常感谢你我真的很高兴谢谢你

以上是关于带有 NSPredicate 的 FetchRequest 不会在新条目上更新的主要内容,如果未能解决你的问题,请参考以下文章

带有核心数据对象的 NSPredicate

带有嵌套数组的 NSPredicate

带有 NSPredicate 的 NSFetchedResultsController 未更新

带有 groupBy 的 nspredicate 不喜欢带有 nsdate 的谓词比较

带有 NSPredicate 的 NSFetchRequest 不返回任何结果

带有特殊字符的 NSPredicate 过滤