Ios NSManagedObjectContext和队列
在与主运行中心和队列打了一段时间交道后,我仍然不确定我是否理解如何正确使用主运行中心和队列。我将分别介绍每种类型的主运行中心:Ios NSManagedObjectContext和队列,ios,objective-c,multithreading,nsmanagedobjectcontext,nsoperationqueue,Ios,Objective C,Multithreading,Nsmanagedobjectcontext,Nsoperationqueue,在与主运行中心和队列打了一段时间交道后,我仍然不确定我是否理解如何正确使用主运行中心和队列。我将分别介绍每种类型的主运行中心: NSMainQueueConcurrencyType 这个其实很简单。它说必须在主队列上运行。这可以通过使用[context performBlock:block]或直接使用它来实现 如果代码在主线程上执行,则可以直接调用主队列样式上下文上的方法,而不是使用基于块的API NSConfinementConcurrencyType 除了创建上下文的线程外,任何线程都不会使
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]...
}];
使用块强> 我将建议做完全相反的事情:始终使用块方法,原因如下: 该块保证每个操作都是计划的,并在下一个操作之前完成。 这有点像在if(){}之后使用{and}。这种做法可以确保您不会因源格式设置而受到错误的约束,并且您正在编写和执行您想要的内容 如果您将块与
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];
如果使用
NSConfinementConcurrencyType
,则只能直接发送消息,该类型仅为向后兼容而存在。此外,可以将基于队列的并发类型与performBlock:
和performBlockAndWait:
结合使用上下文。最后,这可能是最关键的部分:如果使用NSOperation
,则必须在main(对于串行队列)或start(对于并发队列)中创建上下文。在您的示例中,[SUDataManager createChildContext]
必须位于*workQueue的-start,而不是它的NSOperation
。实际上,您可以直接从主线程发送消息(NSPrivateQueueConcurrencyType)。关于NSOperation
,文档中的这一部分似乎讨论了NSConfinementConcurrencyType
,而不是NSPrivateQueueConcurrencyType
。无论如何,这是不清楚的。大多数人肯定同意文件的模糊性。是的,你可以从任何你想要的地方发送消息。文档对两个帐户都很清楚:(1)NSConfinementConcurrencyType
是否存在……以实现向后兼容性;(2)您使用上下文,将基于队列的并发类型与performBlock:
和performBlockAndWait:
结合使用。将这两句话组合起来,只使用NSMainQueueConcurrencyType
和NSPrivateQueueConcurrencyType
和块来满足您的所有需要。因此,对于“它安全吗”这个问题,我倾向于“它可能有效,但我不会这么做”。下面的答案是否提供了解决方案?