基本上,我在我的应用程序中只使用了一个 moc,但我认为在某些情况下我应该使用多个 NSManagedObjectContext。
- 我什么时候应该使用多个 NSManagedObjectContext?
- 听说在某些情况下应该使用3 moc,但不知道在哪些情况下应该使用3 moc?
通常,您希望为NSManagedObjectContext
将访问 Core Data db 的每个线程使用一个单独的线程。这是为了防止对象图由于并发写入同一上下文而可能进入不一致状态。
处理这个问题的最简单方法是NSManagedObjectContext
为每个线程创建一个新线程并共享一个NSPersistentStoreCoordinator
.
在您的 AppDelegate 类型中创建一个属性NSManagedObjectContext
并覆盖 getter 以为每个调用线程返回一个新上下文。通过利用threadDictionary
每个线程的 来做到这一点。
首先,像往常一样设置 managedObjectModel 和 persistentStoreCoordinator。然后在您的 AppDelegate 中创建您的上下文并分配给您的属性:
self.managedObjectContext = [[NSManagedObjectContext alloc] init];
self.managedObjectContext.persistentStoreCoordinator = self.storeCoordinator;
在您的 managedObjectContext getter 覆盖中,使用以下代码为每个调用线程返回一个单独的上下文:
- (NSManagedObjectContext *) managedObjectContext
{
NSThread *thisThread = [NSThread currentThread];
if (thisThread == [NSThread mainThread])
{
//For the Main thread just return default context iVar
return _managedObjectContext;
}
else
{
//Return separate MOC for each new thread
NSManagedObjectContext *threadManagedObjectContext = [[thisThread threadDictionary] objectForKey:@"MOC_KEY"];
if (threadManagedObjectContext == nil)
{
threadManagedObjectContext = [[[NSManagedObjectContext alloc] init];
[threadManagedObjectContext setPersistentStoreCoordinator: [self storeCoordinator]];
[[thisThread threadDictionary] setObject:threadManagedObjectContext forKey:@"MOC_KEY"];
}
return threadManagedObjectContext;
}
}
现在,在您的代码中访问 AppDelegate 的 managedObjectContext 属性的任何地方,您都将确保是线程安全的。
以下链接清楚地解释了何时、为什么以及如何使用多个托管对象上下文。
以下是使用多个托管对象上下文的两个主要原因。
NSManagedObjectContext
线程安全,因为NSManagedObjectContext
不是线程安全的。NSManagedObjectContext
以在 UI 上显示数据。这意味着当您在 UI 上显示数据并从服务器获取数据时,我们应该在 child 上获取数据NSManagedObjectContext
以避免并发和 UI 阻塞问题。对不同的线程使用不同的“moc”
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/Concurrency.html
对于“工作统一”企业模式,你可以回滚你的多次机会——只要它们没有被保存(然后合并回主上下文)
ofc 也用于后台更新等