NSPredicate未执行

这很有趣。 在我的应用程序中,我在数据库中创build了数千个条目(在另一个线程中,我使用的是MagicalRecord)。 一切似乎工作正常(从背景/前景/背景的angular度来看)。

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

- (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对象,如预期的那样
  • 第三:是一个空arrays。

通过debuggingSQL语句,我得到以下内容:

“第一”声明:

CoreData:注释:总计读取执行时间:0行0.0000s。

“第二”声明“:

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 =? ORDER BY t0.ZNAME

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

CoreData:注释:总提取执行时间:两行0.0007s。

“第三”声明:

CoreData:注释:总计读取执行时间:0行0.0000s。

有趣的是,我closures了应用程序(我的意思是真正手动终止它),然后我打开它,所有三个“提取”的声明工作。

为什么第一个和第三个读取语句似乎从未被执行? 如何挖掘问题?

我也有同样的问题,这就是我想到的,以及我如何解决这个问题。

魔法logging有一个根NSManagedObjectContext作为默认NSManagedObjectContext的父项。 当我在默认情况下创build一个NSFetchedResultsController时,一切似乎都很好,就像你一样。

问题是所有新的 NSManagedObject都返回了它们仍然临时的ObjectID 。 所以,就我而言,我正在使用NSPredicate来在关联表上查询范围。 我不只是调用关联方法,因为我不想将所有内容都加载到内存中,并且希望NSFetchedResultsController能够处理更改。

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

显然,子上下文(默认)不能获得转换为非临时ID的好处,即使它已经被保存到后台存储。

更糟糕的情况发生时,我试图用强制obtainPermanentIDsForObjects:error:的问题obtainPermanentIDsForObjects:error: 。 核心数据抱怨说,它不能满足我的实例的错误。 没关系,没有办法,这实际上是一个错误。 刷新对象也没有效果。 我怀疑这是一个核心数据错误,几乎没有人发痒,因为他们只是使用关联方法来获取NSSet。

我的修复是为NSFetchedResultsController使用父上下文,就像在这个问题, 魔法logging,保存和NSFetchedResultsController 。

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

顺便说一句,这只发生在协会的新来源。 一旦有一个实例从启动,它有一个非临时ObjectID ,从来没有问题。