嵌套的performBlock:在NSManagedObjectContext上

时间:2012-05-04 08:22:33

标签: ios core-data nsmanagedobjectcontext

NSPrivateQueueConcurrencyType使用NSMainQueueConcurrencyTypeNSManagedObjectContext类型时, 在同一个上下文中进行嵌套的performBlock调用是否安全?

[backgroundContext performBlock:^{
   NSFetchRequest *myRequest = ...;  
   __block NSArray *result= nil;
   [backgroundContext performBlockAndWait:^{
       results = [backgroundContext executeFetchRequest:myRequest error:NULL];
   }];
}];

这可能看起来很愚蠢,但我有一个现有的代码库,其中包含许多帮助方法,这些方法封装了executeFetchRequest个调用。我不想假设调用者是否已经使用了performBlock。 例如:

-(void)updateObjects:(BOOL)synchronous
{
    if (YES == synchronous)
        [self fetchHelper];
    else
    {
        [backgroundContext performBlock:^{
             [self fetchHelper];
        }];
    }
}

-(NSArray*)fetchHelper
{
     [self.backgroundContext performBlockAndWait:^{
         //Fetch the objects...
         [self.backgroundContext executeFetchRequest: (...)];
     }];
}

我已经尝试过它并且有效。但我已经学会了(艰难的方式)对核心数据和多线程非常小心。

1 个答案:

答案 0 :(得分:8)

是的,performBlockAndWait是可重入的。直接来自Apple的发行说明......

  

Core Data正式化了并发模型   带有新选项的NSManagedObjectContext类。当你创建一个   上下文,您可以指定要与其一起使用的并发模式:   线程限制,专用调度队列或主调度   队列。 NSConfinementConcurrencyType选项提供相同的选项   在5.0之前的iOS版本上出现的行为是   默认。将消息发送到使用队列创建的上下文时   关联,您必须使用performBlock:或performBlockAndWait:   方法,如果您的代码尚未在该队列上执行(对于   主队列类型)或在performBlock ...调用的范围内   (对于私有队列类型)。在传递给那些的块内   方法,您可以自由使用NSManagedObjectContext的方法。该   performBlockAndWait:方法支持API重入。 performBlock:   方法包括自动释放池并调用   完成后的processPendingChanges方法。