在处理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]...
}];
答案 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];
}
}
}];
选择哪种并发类型
NSMainQueueConcurrencyType
虽然技术上可以使用NSConfinementConcurrencyType
作为主线程,并且可能仅用于遗留,但在MainQueue PrivateQueue模型中不需要它。
如何设置后台主题
在后台线程中,设置父上下文。如果您这样做,并且还遵循performBlockAndWait
建议,则所有操作将按顺序进行,并在下一个操作执行之前完成,从而确保数据稳定性。 iCloud不是你想破坏的环境......
self.privateMOC = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[self.privateMOC setParentContext:mainMOC];
[self.privateMOC setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];