在magicalRecord on iOS 7应用程序中,有两个NSManagedObjectContexts:
在执行非常重的数据库时,.sqlite插入/更新/删除如何利用上述两种上下文,从而使数据库保存最终磁盘I/O也发生在后台,而不使用主线程。现在,MagicalRecord中的代码
+ (void)rootContextChanged:(NSNotification *)notification {
if ([NSThread isMainThread] == NO) {
dispatch_async(dispatch_get_main_queue(), ^{
[self rootContextChanged:notification];
});
return;
}
[[self MR_defaultContext] mergeChangesFromContextDidSaveNotification:notification];}
使用主线程将数据保存到数据库。相反,整件事不可能发生在没有主线程干预的背景下。虽然MagicalRecord公开了用于创建后台NSManagedObjectContext的方法(如MR_Context ),但是在主线程上执行保存操作。我在GCD中创建背景上下文,然后像这样使用performBlockAndWait:
if ([bContext hasChanges]) {
NSError* __autoreleasing error;
[bContext save:&error];
[bContext.parentContext saveToPersistentStoreAndWait];
}发布于 2014-01-16 19:39:18
我不能用魔法唱片说话,因为我从未用过它。
但是关于可能性,假设您使用了SQLite存储,有一个小问题: SQLite不允许同时进行多线程访问。根据它的开发人员“线是邪恶的,要避开它们。”
在核心数据术语中,这通常意味着从背景上下文实例化保存,SQL插入、删除等都发生在后台,写磁盘发生在后台等等,但当这种情况发生时,对持久存储的所有访问都被锁定。如果主队列试图运行查询,甚至只是对象中的错误,那么它必须阻塞,等待保存完成。
因此,至少在一个非常真实的意义上,您不能保证主线程不会受到任何影响,除非您能够保证主线程不会试图访问存储。
常见的解决方案包括在主队列上使用带有显式SQL样式获取的托管对象的字典版本,而不一定在主队列上使用,因为不可变的字典是线程安全的,使用由Core数据构建的其他自定义结构,但随后不太可能引用它,只是不担心后台保存相对较短,而且不太可能单击,或者甚至将后台的保存分割成小块,以减少主队列可能阻塞的最大时间。但是,对于最后一个对象要小心,因为插入成本在SQLite中是非线性的,因此,例如插入五个十个对象比插入五十个对象花费的时间更长。
我还设法从抓取任何我认为用户可能希望在不久的将来在主线程,当后台宣布,它计划很快保存一些良好的里程。
https://stackoverflow.com/questions/21171073
复制相似问题