8

这很有趣。在我的应用程序中,我在数据库中创建了数千个条目(在另一个线程中,我使用的是 MagicalRecord)。一切似乎都很好(从背景/前景/上下文的角度来看)。

当我在主线程中尝试获取“刚刚插入”的数据时,我发现了以下行为:

- (NSArray *) familiesInCompany:(Company *) company {
  NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"company == %@", company];
  NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"company.name == %@", company.name];

  NSArray *first = [Family MR_findAllSortedBy:@"name" ascending:YES withPredicate:predicate1];
  NSArray *second = [Family MR_findAllSortedBy:@"name" ascending:YES withPredicate:predicate2];
  NSArray *third = [Family MR_findByAttribute:@"company" withValue:company andOrderBy:@"name" ascending:YES];

  return second;
}

现在我得到的是:

  • 首先:是一个空数组
  • 第二:包含所有Family对象,如预期的那样
  • 第三:是一个空数组。

通过调试 SQL 语句,我得到以下信息:

“第一个”声明:

CoreData:注释:总提取执行时间:0 行 0.0000 秒。

“第二个”声明“:

CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZCOMPANY FROM ZFAMILY t0 JOIN ZCOMPANY t1 ON t0.ZCOMPANY = t1.Z_PK WHERE t1.ZNAME = ? 按 t0.ZNAME 订购

CoreData:注解:sql连接获取时间:0.0005s

CoreData:注释:总提取执行时间:2 行 0.0007 秒。

“第三”声明:

CoreData:注释:总提取执行时间:0 行 0.0000 秒。

有趣的是我关闭了应用程序(我的意思是真正手动终止它)然后我打开它,所有三个“获取”语句都起作用。

为什么第一个和第三个 fetch 语句似乎永远不会被执行?如何深挖问题?

4

1 回答 1

8

我有同样的问题,这是我想出来的,以及我是如何解决的。

Magical Record 有一个 rootNSManagedObjectContext作为 default 的父级NSManagedObjectContext。当我在默认上下文中创建NSFetchedResultsController时,一切似乎都正常,就像你一样。

问题是所有 NSManagedObject的都带着他们仍然是临时ObjectID的。因此,就我而言,我使用 anNSPredicate来确定关联表上的查询范围。我不只是调用关联方法,因为我不想将所有内容加载到内存中并且想要NSFetchedResultsController处理更改,对我来说。

使用临时ObjectID查询找到零个结果,这正是它显示的内容。

显然,子上下文(默认)没有从转换为非临时 ID 的好处,即使它已被持久化到后备存储。

当我试图用obtainPermanentIDsForObjects:error:. Core Data 抱怨它无法满足我的实例的故障。没关系,这不可能实际上是一个错误。简单地刷新对象也没有效果。我怀疑这是一个核心数据错误,几乎没有人会发痒,因为他们只是使用关联方法来获取 NSSet。

我的解决方法是使用父上下文NSFetchedResultsController,就像在这个问题中一样,Magical Record、saving 和 NSFetchedResultsController

我已经在编辑时将默认值包装在一个新的子上下文中,因此,使用 将实例复制到该编辑上下文中,因此除了添加到参数createInContext之外,我不需要做任何额外的工作。.parentContext

顺便说一句,这只发生在关联来源的新实例上。一旦一个实例从启动就在那里,它有一个非临时的ObjectID并且从来没有问题。

于 2012-07-10T05:56:06.220 回答