NSManagedObjectContext performBlock 内的 dispatch_async(dispatch_get_main_queue()

Posted

技术标签:

【中文标题】NSManagedObjectContext performBlock 内的 dispatch_async(dispatch_get_main_queue()【英文标题】:dispatch_async(dispatch_get_main_queue() inside NSManagedObjectContext performBlock 【发布时间】:2014-11-26 21:29:34 【问题描述】:

我想做的是在后台线程上创建一个异步核心数据任务,以免破坏主线程,但我也想在工作完成后做主线程工作......

这是我的任务

  -(void)doTaskwithCompletion:(coreDataCompletion)complete
  
    [self.backgroundManagedObjectContext performBlock:^

        // do my BG core data task

        [self saveContext:self.backgroundManagedObjectContext];
        complete(YES);

    ];
   

这是我的块方法

            [[MYCoreDataManager sharedInstance]doTaskwithCompletion:^(BOOL complete) 

                if (complete == YES) 

                    dispatch_async(dispatch_get_main_queue(), ^

                         // back to the main thread                            
                    );
                

            ];

有些东西告诉我这是错误的......但是一旦块完成后我找不到另一种方法让自己回到主线程......通知似乎太笨拙了。

我想简而言之,我的问题是我可以在 moc performBlock:^ 中调用 dispatch_async(dispatch_get_main_queue() 吗?

基本上

  -(void)doTaskwithCompletion:(coreDataCompletion)complete
  
    [self.backgroundManagedObjectContext performBlock:^

        // do my BG core data task

        [self saveContext:self.backgroundManagedObjectContext];
        dispatch_async(dispatch_get_main_queue(), ^

           // back to the main thread    

        );

    ];
   

【问题讨论】:

有什么问题?为什么你认为你做不到? 【参考方案1】:

我想你知道调用异步内容并在内部返回 mainQueue 是一种非常常见的模式,即用于更新 UI:

dispatch_async(globalQueue, ^
    // do something
    dispatch_async(mainQueue, ^ 
        // update UI
    );
);

由于您已经将变量命名为self.backgroundManagedObjectContext,因此您可能对Multi-Context CoreData 心存疑虑,我理解您的担忧。只要您不尝试使用此块为 CoreData 更改某些内容(在任何上下文中),您可能就可以了。

只需确保为上下文使用正确的初始化程序,即[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

【讨论】:

是的,这一切都是正确的......我不确定 performBlock 是否被视为 GCD ......但 NSPrivateQueueConcurrencyType 已设置......所以如果它与您的示例基本相同,那么我很高兴!【参考方案2】:

“简而言之,我想我的问题是我可以在 moc performBlock:^ 中调用 dispatch_async(dispatch_get_main_queue() 吗?”

答案是肯定的!实际上,当您从主线程调用 performBlock 时,您正在做相反的事情,对吧?这是ios的一个共同特点。一种更简洁的方法可能是传入一个完成,并在该完成中调用 main...

现在,你有:

dispatch_async(dispatch_get_main_queue(), ^

       // back to the main thread  
       completion()



    );

你也可以写:

-(void)doTaskwithCompletion:(coreDataCompletion)complete

[self.backgroundManagedObjectContext performBlock:^

    // do my BG core data task

    [self saveContext:self.backgroundManagedObjectContext];
    complete()

];

其中完成了对主线程的调用。

【讨论】:

好的,这样可以吗?伟大的!然后,我的代码中的其他地方出现了奇怪的问题……我会调查的。谢谢!

以上是关于NSManagedObjectContext performBlock 内的 dispatch_async(dispatch_get_main_queue()的主要内容,如果未能解决你的问题,请参考以下文章

NSManagedObjectContext:撤消保存操作?

声明 NSManagedObjectContext 时出错

CoreData 多 NSManagedObjectContext 保存通知说明

NSManagedObjectContext 类别

NSManagedObjectContext: performBlockAndWait vs performBlock 通知中心

如何清除 NSManagedObjectContext 中的所有对象?