NSManagedObjectContext和队列

时间:2014-07-15 06:27:19

标签: ios objective-c multithreading nsmanagedobjectcontext nsoperationqueue

在处理MOC和队列一段时间之后,我仍然不确定我是否理解如何以正确的方式使用MOC和队列。我将分别处理每种类型的MOC:

NSMainQueueConcurrencyType

这个实际上很容易。它说必须在主队列上运行。这可以使用[context performBlock:block]或直接从主线程中使用来实现。

  

如果您的代码在主线程上执行,您可以直接调用主队列样式上下文中的方法,而不是使用基于块的API。

NSConfinementConcurrencyType

  

除了您创建它的线程之外的任何线程都不会使用该上下文

这对于队列来说意味着什么,即使是不承诺一直使用同一线程的串行队列呢?

NSPrivateQueueConcurrencyType

  

上下文创建并管理私人队列

我是否必须通过[context performBlock:block]使用此队列进行所有处理?

我可以直接在我以类似于NSMainQueueConcurrencyType的方式定义的单个串行队列中使用它吗?

或换句话说,执行以下操作是否安全:

NSOperationQueue *workQueue = [[NSOperationQueue alloc] init];
workQueue.maxConcurrentOperationCount = 1;

[workQueue addOperationWithBlock:^{
    // It just creates a new MOC with some parent
    _context = [SUDataManager createChildContext]; 
    // .... Do things with context without [_context performBlock:block]...
}];

1 个答案:

答案 0 :(得分:0)

使用块!

我建议完全相反:总是使用块方法,这就是原因:

该块确保每个操作都已安排并在下一个操作之前完成。 这有点像在if(){}之后使用{和}。这种做法可确保您不会因源格式化而受到错误的约束,并且您正在编写并执行您的预期。

如果将块与performBlockAndWait组合在一起,则无法进入比赛。因此,除非你有充分的理由不这样做,并且有足够的时间来备份和调试iCloud,我每次都会选择强大的方法。

示例:

[self.mainMOC performBlockAndWait:^{
    __strong myClass * strongSelf = weakSelf;
    if(strongSelf) {
        if( [strongSelf.mainMOC hasChanges]) {
            NSError *error = nil;
            [strongSelf.mainMOC save:&error];
        }
    }
}];

选择哪种并发类型

  1. 主要线程:使用NSMainQueueConcurrencyType
  2. 任何其他线程:使用`NSPrivateQueueConcurrencyType。
  3. 虽然技术上可以使用NSConfinementConcurrencyType作为主线程,并且可能仅用于遗留,但在MainQueue PrivateQueue模型中不需要它。

    如何设置后台主题

    在后台线程中,设置父上下文。如果您这样做,并且还遵循performBlockAndWait建议,则所有操作将按顺序进行,并在下一个操作执行之前完成,从而确保数据稳定性。 iCloud不是你想破坏的环境......

    self.privateMOC = [[NSManagedObjectContext alloc]
        initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [self.privateMOC setParentContext:mainMOC];
    [self.privateMOC setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];