不推荐使用dispatch_get_current_queue(),是否有安全CoreData的替代方案?

时间:2013-08-29 12:23:12

标签: ios core-data grand-central-dispatch

许多人提出的问题类似,但目的却截然不同:

CoreData 需要,如果您允许方法调用来自其他类(其中),您可以跟踪当前队列,当前线程和当前NSOperationQueue(如果您是NSOperation) ,默认情况下,每个类允许)。对此没有“可能”:这是一个很难的要求。

这很好,一般来说很容易确保:

NSAssert( [NSThread currentThread].isMainThread || myPrivateQueue == dispatch_get_current_queue(), @"You tried to call this method from an external thread, or a queue other than my internal private queue. That's not legal, and will cause data corruption" );

...除了Apple已经弃用了dispatch_get_current_queue(),显然是“因为人们滥用它来解决他们不理解的GCD / GCD中缺少的功能”。

注意:我对上面的dispatch_get_current_queue()的使用似乎是正确的和非滥用的,从Apple的标题评论判断:整点是我正在检查队列是我创建的私有队列(Apple声称是可接受的用法)。

撇开贬低某些东西的智慧,仅仅因为它的实现存在缺陷:( ......有人找到了解决这个问题的方法被Apple删除。具体来说:使用CoreData,你必须跟踪队列 - 是否有另一种方式这样做?

(这很重要,因为:使用CoreData,如果你允许某些东西意外地调用这样的方法,你就不会出现“崩溃”,你会得到“数据腐败,将来会在某些时候显示出来”修复它已经太晚了“)

2 个答案:

答案 0 :(得分:4)

performBlock总是以正确的线程运行它。只需使用:

[yourManagedObjectContext performBlock:^{
//do your stuff here
}];

您不再需要跟踪当前上下文,因为您的MOC知道哪个线程首先触发此MOC。当您使用performBlockperformBlockAndWait时,您就是安全的。

答案 1 :(得分:0)

在我的具体情况中,我将所有performBlock调用替换为:

  1. 将所有CoreData操作移至单个类
  2. 创建私人dispatch_queue
  3. 将我的所有内部通话合并为一个通话
  4. 单个调用将自己包装在dispatch_async((私有内部队列)中)
    1. ...并且它在调度中执行的第一件事是“if(self.privateMOC == nil)”...并创建本地MOC,保证只在该队列中访问和创建MOC
  5. 发生了两件事:

    1. 互斥锁/锁挂起都消失了(虽然这可能是巧合 - 如果事实证明锁仍然陷入僵局,我会稍后报告)
    2. 性能明显优于performBlock:随处使用
      1. 注意:我们有很多performBlock调用,并且经常这样做(敏感数据需要以适度高的频率更改CoreData MOC内容)。我不知道它在普通应用程序中是否会有明显区别
    3. ...所以,就目前而言,就我的目的而言:这已被证明是一个很好的解决方案。我不相信这是问题的“正确”通用答案,但是......我推荐给其他发现“performBlock”不是万能的灵丹妙药。