只能在使用队列创建的NSManagedObjectContext上使用-performBlock:方法

7

我想在Core Data中使用多线程。我将xml文件解析到NSManagedObject中。我使用下面的代码,但是出现了运行时错误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个回答

31

performBlock 只能与 NSMainQueueConcurrencyTypeNSPrivateQueueConcurrencyType 的托管对象上下文(MOC)一起使用。在您的情况下,您应该使用以下方式创建上下文:

NSManagedObjectContext *context = [[NSManagedObjectContext alloc]
                     initWithConcurrencyType:NSPrivateQueueConcurrencyType];

无需创建调度队列或使用 dispatch_async()。 MOC(管理对象上下文)会创建和管理自己的队列,并且performBlock 会确保块在MOC的队列上执行。


如果文档上对这一点不是那么含糊的话就好了...我还在用dispatch块包装initWithConcurrencyType:方法,并创建自定义队列,因为文档暗示你必须这样做...谢谢! - Rob Glassey
@RobGlassey:不幸的是,“Core Data编程指南”尚未针对新的并发类型进行更新,只有在“OS X v10.7和iOS 5.0的Core Data发布说明”中才有记录。(http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-CoreData/index.html) - Martin R
啊哈,就在那里!清晰明了。不过,iOS 5 真的还没有发布多久……他们很可能会在不久的将来将像这样的重要信息移入主参考指南中。 - Rob Glassey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接