2012-05-04 123 views
8

当使用NSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyType类型NSManagedObjectContext, 是否可以安全地在同一个上下文中执行嵌套的performBlock调用?嵌套performBlock:在NSManagedObjectContext

[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: (...)]; 
    }]; 
} 

我试过了,它的工作原理。但我已经学会了(很难)对Core Data和多线程非常小心。

回答

8

是,performBlockAndWait是折返。直接从Apple的发行说明...

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

+0

什么performBlock,是重入吗? – malhal

+0

这不是,这是在会议中讨论。如果您调用performBlock,您的请求将排队,因为它是异步的。 –

+0

只是要清楚,OP在第二位代码中所做的是可以做到的,但是如果两种方法都有“performBlock”,会导致问题?这是正确的方式来看待这个? – hokkuk