只能在使用队列创建的 NSManagedObjectContext 上使用 -performBlock:
Posted
技术标签:
【中文标题】只能在使用队列创建的 NSManagedObjectContext 上使用 -performBlock:【英文标题】:Can only use -performBlock: on an NSManagedObjectContext that was created with a queue 【发布时间】:2013-07-15 08:39:39 【问题描述】:我想在 Core Data 中使用多线程。我在NSManageObject
s 中解析 xml 文件。我使用下面的代码,我得到运行时错误Can only use -performBlock: on an NSManagedObjectContext that was created with a queue
。怎么了?
//xmlParser
- (void)main
dispatch_queue_t queueB = dispatch_queue_create("Create Books", NULL);
dispatch_async(queueB, ^
// Opening xml
// ...
NSManagedObjectContext* context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:mainContext].persistentStoreCoordinator];
[context performBlock:^
// ...
[self _parseNode:container_node appendTo:books inContext:context];
// ...
NSError* error = nil;
[context save:&error];
[mainContext performBlock:^
NSError* parentError = nil;
[mainContext save:&parentError];
];
];
[context release];
);
dispatch_release(queueB);
- (int)_parseNode:(axlNode*)inode appendTo:(NSMutableArray*)ioarray inContext:(NSManagedObjectContext*)context
// ...
[context executeFetchRequest:request error:&error];
//...
【问题讨论】:
【参考方案1】:performBlock
只能与NSMainQueueConcurrencyType
的托管对象上下文 (MOC) 或
NSPrivateQueueConcurrencyType
。在您的情况下,您应该使用
NSManagedObjectContext *context = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSPrivateQueueConcurrencyType];
并且不需要创建调度队列或使用dispatch_async()
。
MOC 创建和管理自己的队列,
而performBlock
确保该块在 MOC 的队列中执行。
【讨论】:
如果文档在这一点上不是那么模糊...我仍然将 initWithConcurrencyType: 包装在一个调度块中并创建一个自定义队列,因为文档暗示您必须这样做。 .. 谢谢! @RobGlassey:不幸的是,“核心数据编程指南”尚未针对新的并发类型进行更新,它仅记录在 "Core Data Release Notes for OS X v10.7 and ios 5.0" 中。 啊哈,就是这样!清如白昼。尽管如此,iOS 5 还没有真正推出那么久......他们可能会在不久之后将像这样的基本花絮移到主要参考指南中。以上是关于只能在使用队列创建的 NSManagedObjectContext 上使用 -performBlock:的主要内容,如果未能解决你的问题,请参考以下文章