当使用
NSPrivateQueueConcurrencyType
和NSMainQueueConcurrencyType
类型的NSManagedObjectContext
时,对同一个上下文进行嵌套调用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: (...)];
}];
}
我已经尝试过它并且它有效。但是我(吃了亏)学会了在使用核心数据和多线程时要非常小心。
performBlockAndWait
,并且我尽一切可能避免使用它。它很容易死锁(必须知道调用它的上下文,否则可能会死锁),而且它违反了FIFO原则(嵌套调用立即执行并“跳过”等待异步块的队列)。这在iOS8中的新异步获取中更为明显。 - Jody Hagins