CoreData + MagicalRecord - 我是否正确保存了详细信息?

Kyl*_*yle 5 cocoa core-data magicalrecord

Applications我的数据库中有三个.我有一个删除一个谓词.

给出以下代码:

[Application MR_deleteAllMatchingPredicate: applicationDeletePredicate];
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];

NSLog(@"We have %ld apps left.", [Application MR_countOfEntities]);

dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"We have %ld apps left.", [Application MR_countOfEntities]);
});
Run Code Online (Sandbox Code Playgroud)

我收到以下日志消息:

We have 2 apps left.

We have 3 apps left.

所以它已经正确删除了谓词,但是当我尝试在主队列中重新加载时,应用程序仍然存在.我做错了吗?我应该在处理时总是指定默认上下文MagicalRecord(在我的计数方法中)吗?

eof*_*ter 11

尽管MagicalRecord确实提供了减少键入的方法,但您需要了解幕后发生的事情以避免出现类似情况.

特别是,您需要了解MagicalRecord何时创建新上下文以及如何配置它们.

MagicalRecord为需要上下文的操作提供方法,但这些方法不将上下文作为参数.在这些情况下,MagicalRecord使用[NSManagedObjectContext MR_contextForCurrentThread]方法来获取默认上下文或创建一个新的上下文,该上下文是默认上下文的子项.如果它创建了一个新的上下文,它会为当前线程缓存它以供以后重用(考虑到Apple使用队列并发类型的上下文的方向,这是一个不好的做法,你可以使用块内的对象).

但长话短说,这里可能会发生什么.

  1. 您提供的代码在后台线程上运行.
  2. [Application MR_deleteAllMatchingPredicate: applicationDeletePredicate]; 创建一个新的上下文,它是默认上下文的子项并执行删除.
  3. [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; (顺便说一句,这是非主要线程的非法调用,考虑到1.),保存了不知道删除的默认上下文,因为从未保存子上下文,并且没有将更改推送到父,默认,上下文.
  4. [Application MR_countOfEntities] 在第一个NSLog中,操作与删除操作相同,并返回新计数.
  5. [Application MR_countOfEntities]在第二个NSLog中运行在主队列上.因为它在主线程上运行,所以它使用默认上下文,从未看到过这个删除,因为child从未保存过.所以它返回旧计数.

您需要做的是确保保存子上下文及其所有父项.所以你可能需要用当前线程的上下文替换第二行中的默认上下文:[[NSManagedObjectContext MR_contextForCurrentThread] MR_saveToPersistentStoreAndWait];.

但我会避免隐藏的上下文创建,并明确地创建它们.所以我的第一个建议是避免使用不将上下文作为参数的MagicalRecord方法(当有类似的方法时).

我的第二个建议是不使用MagicalRecord,而是直接使用Core Data.首先,您可以使用全局使用的两个上下文:一个具有主队列并发类型的上下文,您将在主线程上使用它来更新UI.另一个具有私有队列并发类型,您将用于所有后台任务,并将其配置为主上下文的子级.