我可以将ManagedObjectContext的父上下文设置为具有不同并发类型的ManagedObjectContext吗?例如:
backgroundManagedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[backgroundManagedObjectContext_ setPersistentStoreCoordinator:coordinator];
managedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[managedObjectContext_ setParentContext:backgroundManagedObjectContext_];
Run Code Online (Sandbox Code Playgroud)
我的目标是(希望)获得managedObjectContext_的快速保存(因为它只需要将内容保存到父内存上下文中),然后让backgroundManagedObjectContext_在其自己的队列中执行保存.除非我碰巧需要在后台保存之前从"前台"队列执行另一次保存,否则我的用户永远不会看到很长的保存时间.
我遇到了看起来像死锁的东西,但我不确定它们是否与此相关,或者我的问题是否在其他地方.
我可以或多或少地可靠地产生死锁的地方的详细信息:
我有一个主线程的托管对象上下文,它由具有私有队列并发类型的托管对象上下文支持,并且具有持久性存储.
我有一些实体类型(大约5个),每个实体类型与另一个实体有一个或两个双向关系.
我的应用程序想要使用iCloud(我已经为这些测试拨打了代码),因此它无法附带预先填充的数据库,它需要在检测到空数据库时构建它.
因此,当我看到一个空数据库(在主线程上检查)时,我添加了除了一个实体类型之外的所有类型中的4个或8个,并且最后一个获得大约100个(所有添加都发生在主线程上).主线程执行saveContext.在完成之后(没有错误),它要求其他托管对象上下文运行也执行saveContext的块.这个saveContext绝对是一个死锁参与者.这也是使用"背景"NSManagedObjectContext完成的唯一内容.
在此之后,确切的控制流程有点模糊,因为NSFetchedResultsController(所有给定实体类型(具有~3个成员)具有简单排序,批量大小为20左右)驱动下一轮Core Data活动,但是有来自TableViewController的调用询问它需要管理多少项,即"获取的结果控制器有多少结果".那个电话是僵局的另一面.(这一切都在主线程中)
我试图设计一个帮助方法,它将检索UIManagedDocument,然后打开并返回它,以便我可以从我的应用程序中的几个地方访问相同的UIManagedDocument.
由于我对块不太熟悉,因此我遇到了异步性问题.理想情况下,事件的顺序是这样的:
我可以通过某种方式传递原始块吗?
到目前为止,这是我的代码.任何想法都非常感谢,谢谢.
// This is a dictionary where the keys are "Vacations" and the objects are URLs to UIManagedDocuments
static NSMutableDictionary *managedDocumentDictionary = nil;
// This typedef has been defined in .h file:
// typedef void (^completion_block_t)(UIManagedDocument *vacation);
// The idea is that this class method will run the block when its UIManagedObject has opened
@implementation MyVacationsHelper
+ (void)openVacation:(NSString *)vacationName usingBlock:(completion_block_t)completionBlock
{
// Try to retrieve the relevant UIManagedDocument from managedDocumentDictionary
UIManagedDocument *doc …Run Code Online (Sandbox Code Playgroud)