为什么我所有的NSManagedObjects都立即出错?

我正在运行一个非常基本的获取请求,返回约2000个对象。 我正在使用批处理大小为15的NSFetchedResultsController。

predicate= [NSPredicate predicateWithFormat:@"ANY tags.tagName==%@", currentTagObject.tagName]; [fetchRequest setPredicate:predicate]; NSSortDescriptor *sort= [[NSSortDescriptor alloc] initWithKey:@"createDate" ascending:NO selector:@selector(compare:)]; [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]]; [fetchRequest setFetchBatchSize:15]; self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:@"createDay" cacheName:nil]; 

提取请求需要超过10秒。 我已经启用SQLitedebugging,所以我可以看到发生了什么事情。 我认为它是2000年的所有实体,只有15个实际价值的实体,然后由于某种原因经历了2000年的每一个对象,并使其失败。

在提取过程中,这些行出现几千次:

 2012-06-22 21:14:47.546 app[9227:707] CoreData: annotation: sql connection fetch time: 0.0107s 2012-06-22 21:14:47.551 app[9227:707] CoreData: annotation: total fetch execution time: 0.0171s for 15 rows. 2012-06-22 21:14:47.568 app[9227:707] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZAUTHOREMAIL, t0.ZAUTHORNAME, t0.ZCREATEDATE, t0.ZISGLOBAL, t0.ZISLOCKED, t0.ZISNEW, t0.ZISPENDINGDELETE, t0.ZISPENDINGSYNC, t0.ZLASTUPDATED, t0.ZLOCALLYMODIFIEDDATE, t0.ZMETALASTUPDATED, t0.ZNOTEID, t0.ZNUMBEROFCHILDREN, t0.ZPARENTAUTHOREMAIL, t0.ZPARENTNOTEID, t0.ZROOTAUTHOREMAIL, t0.ZROOTNOTEID, t0.Z4PENDINGADDNOTES, t0.Z4PENDINGREMOVENOTES FROM ZMBNOTEOBJECT t0 WHERE t0.Z_PK IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY t0.ZCREATEDATE DESC LIMIT 15 ...thousands more lines exactly similar to the three above 

我的表格每次只显示5个单元,所以我不知道为什么所有的对象都立即出错了。 什么可能导致这个? 为什么所有的对象都会立即出错,甚至没有我滚动我的桌子? 它可能是他们被访问的地方,也许迭代? 调用NSArray *fetchedObjects = fetchedResultsController.fetchedObjects会导致所有的对象有任何机会吗?

看看有关batchSize (我的重点)文档中说:

默认值为0.批处理大小0被视为无限,这将禁用批处理错误行为。

如果设置非零批处理大小,则执行提取时返回的对象集合将分解为批处理。 当执行提取操作时, 将对整个请求进行评估,并logging所有匹配对象的身份,但是batchSize只能从持久存储 提取不超过batchSize对象的数据 。 从执行请求返回的数组将是一个代理对象,可按需透明地对批处理进行故障排除。 (在数据库方面,这是一个内存游标。)

您可以使用此function来限制应用程序中的工作集数据。 结合fetchLimit,您可以创build任意结果集的子范围。

所以很明显,根据这个解释,你可以在商店里进行2000/15次往返。 这肯定需要一些时间。 你需要所有的数据,因为你的sorting和ANY谓词,但你指示的请求,一次只得到15。

此外,为了完整性,从以前的评论:从您的sorting描述符中删除compare

“核心数据编程指南”在“ 批处理错误和预取”段落中详细描述了您所看到的行为。

简而言之,如果您使用谓词来获取具有特定名称标签的对象,则应该预取标签对象。 这是因为通常在读取对象时,Core Data不会获取相关的对象,而是使用错误。 现在你的谓词触发器单独发射那些很慢的故障。