Ios 嵌套的performBlock:在NSManagedObjectContext上

Ios 嵌套的performBlock:在NSManagedObjectContext上,ios,core-data,nsmanagedobjectcontext,Ios,Core Data,Nsmanagedobjectcontext,使用NSPrivateQueueConcurrencyType和NSMainQueueConcurrencyType类型进行NSManagedObjectContext时, 在同一上下文上进行嵌套的performBlock调用安全吗 [backgroundContext performBlock:^{ NSFetchRequest *myRequest = ...; __block NSArray *result= nil; [backgroundContext perfo

使用
NSPrivateQueueConcurrencyType
NSMainQueueConcurrencyType
类型进行
NSManagedObjectContext
时, 在同一上下文上进行嵌套的performBlock调用安全吗

[backgroundContext performBlock:^{
   NSFetchRequest *myRequest = ...;  
   __block NSArray *result= nil;
   [backgroundContext performBlockAndWait:^{
       results = [backgroundContext executeFetchRequest:myRequest error:NULL];
   }];
}];
这可能看起来很愚蠢,但我有一个现有的代码库,其中包含许多helpers方法,这些方法封装了
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是可重入的。直接来自苹果的发行说明

核心数据将数据库的并发模型形式化 具有新选项的NSManagedObjectContext类。当您创建 在上下文中,可以指定要与之一起使用的并发模式: 线程限制、专用调度队列或主调度 队列NSConfinementConcurrencyType选项提供了相同的功能 在5.0之前的iOS版本上出现的行为,并且是 违约将消息发送到使用队列创建的上下文时 关联时,必须使用performBlock:或performBlockAndWait: 方法,如果您的代码尚未在该队列上执行(对于 主队列类型)或在performBlock的范围内。。。调用 (对于专用队列类型)。在传递给那些 方法,您可以自由使用NSManagedObjectContext的方法。这个 performBlockAndWait:方法支持API可重入性。穿孔锁: 方法包括自动释放池并调用 processPendingChanges方法在完成时更改


那performBlock呢,它也是可重入的吗?它不是,这在会话中有介绍。如果调用performBlock,请求将排队,因为它是异步的。请澄清,OP在代码的第二位中所做的是可以做的,但如果两个方法都有“performBlock”,则可能会导致问题?这是正确的看法吗?这取决于你对OK的定义。我不会那样做。我的经验法则是,
performBlockAndWait
的使用仅适用于例外情况,我尽量不使用它。这是一个等待发生的死锁(您必须知道调用它的上下文,否则可能会死锁),并且它违反了FIFO原则(现在执行嵌套调用并“跳转”等待异步块的队列)。iOS8中新的异步抓取更是如此。@JodyHagins。关于performBlockAndWait和FIFO原理的一个小说明。当调用方调用带有队列的CoreData上的PerformBlock和Wait时,队列不会将新块放在所有其他异步队列项的前面。调用线程只是等待其块执行,然后返回。到那时,所有其他异步块都已执行。当涉及嵌套的performBlockAndWait时,同样的原则也会死锁。(这就像在主线程上运行时在主线程上调用dispatch_sync)。但CoreData的performBlockAndWait已重新进入,以避免死锁。