带有 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 的 NSFetchedResultsController 未更新
带有 groupBy 的 nspredicate 不喜欢带有 nsdate 的谓词比较