问题:如何获取子上下文以查看父上下文中保留的更改,以便它们触发我的NSFetchedResultsController来更新UI?
这是设置:
你有一个下载并添加大量XML数据的应用程序(大约200万条记录,每条记录大致与正常段落的文本大小相同).sqlite文件的大小约为500 MB.将此内容添加到Core Data需要时间,但您希望用户能够在数据以递增方式加载到数据存储中时使用该应用程序.用户必须看不到大量数据被移动,因此没有挂起,没有抖动:滚动像黄油一样.尽管如此,该应用程序更有用,添加的数据越多,因此我们不能永远等待将数据添加到Core Data存储中.在代码中这意味着我真的想在导入代码中避免这样的代码:
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
Run Code Online (Sandbox Code Playgroud)
该应用仅限iOS 5,因此需要支持的最慢设备是iPhone 3GS.
以下是我目前用于开发当前解决方案的资源:
iDeveloper TV - 适用于Mac,iPhone和iPad更新的核心数据
我有3个NSManagedObjectContext实例:
masterManagedObjectContext - 这是具有NSPersistentStoreCoordinator的上下文,负责保存到磁盘.我这样做,所以我的保存可以是异步的,因此非常快.我在发布时创建它,如下所示:
masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[masterManagedObjectContext setPersistentStoreCoordinator:coordinator];
Run Code Online (Sandbox Code Playgroud)
mainManagedObjectContext - 这是UI在任何地方使用的上下文.它是masterManagedObjectContext的子代.我像这样创建它:
mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[mainManagedObjectContext setUndoManager:nil];
[mainManagedObjectContext setParentContext:masterManagedObjectContext];
Run Code Online (Sandbox Code Playgroud)
backgroundContext - 此上下文在我的NSOperation子类中创建,该子类负责将XML数据导入Core Data.我在操作的main方法中创建它并将其链接到那里的主上下文.
backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[backgroundContext setUndoManager:nil];
[backgroundContext setParentContext:masterManagedObjectContext];
Run Code Online (Sandbox Code Playgroud)
这实际上非常非常快.只需通过这3个上下文设置,我就可以将导入速度提高10倍以上!老实说,这很难相信.(此基本设计应该是标准Core Data模板的一部分......)
在导入过程中,我保存了两种不同的方式.我在背景上下文中保存的每1000个项目:
BOOL saveSuccess …Run Code Online (Sandbox Code Playgroud) core-data nsfetchedresultscontroller nsmanagedobjectcontext ios
我已经能够在我的应用程序上确认这一点,并且我创建了一个快速示例应用程序来确认这一点.这是设置:
您有两个托管对象上下文:
masterMOC: NSPrivateQueueConcurrencyType, tied to persistent store coordinator
mainMOC: NSMainQueueConcurrencyType, child of masterMOC, NOT tied to any store coordinator
Run Code Online (Sandbox Code Playgroud)
此设置的灵感来自WWDC视频,它建议我们可以通过将其设置masterMOC为专用队列并将其绑定到持久性存储来保存后台线程.如果你设置了一个NSFetchedResultsController使用mainMOC(并且它必须是mainMOC那个与UI绑定的那个),并设置a fetchBatchSize,则忽略批量大小并且所有实体立即出现故障.我启用了SQLite调试注释,当滚动数千行(批量大小为20)时,没有任何错误被触发.
如果我进行一个简单的调整,即将持久性存储协调器绑定到mainMOC并使其成为根上下文(即,它不再是master的子节点),那么批量大小完美地工作,并且当我滚动数千行时,几个故障被解雇了.
这是预期的行为吗?我错过了什么吗?
您可以在此处下载示例项目