Dav*_*vid 7 multithreading core-data objective-c thread-safety

以上是我的模型的简化.我的应用程序有一个NSWindowController对象控制用户和帐户实体的两个NSViewController对象.当用户登录应用程序时,他们可以通过调出相关的视图控制器来修改用户或帐户信息.在后台,我让应用程序在一个单独的线程上定期在应用程序委托中填充用户的日志.
我正在使用一个单独NSManagedObjectContext的后台线程和应用程序委托NSManagedObjectContext用于视图控制器中的数据输入.我想知道一些事情:
1)这是一个好习惯吗?我应该NSManagedObjectContext为每个视图控制器创建一个,然后在用户完成更改时合并上下文吗?
2)因为日志实体是在后台线程中创建的,所以它有自己的NSManagedObjectContext.但是,每个日志都包含来自用户和帐户实体的信息,这些信息是在应用程序代理中创建的NSManagedObjectContext.这就是我提取用户的方式:
- (NSManagedObjectID*) fetchUser:(NSString*) userID {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"user":inManagedObjectContext:self.managedObjectContext];
/** snip **/
}
Run Code Online (Sandbox Code Playgroud)
后台线程调用此方法如下:
NSManagedObjectID* userObjectID = [self fetchUser:userID];
NSManagedObject* userObject = [self.logsManagedObjectContext objectWithID:userObjectID];
Run Code Online (Sandbox Code Playgroud)
我在fetchUser线程安全方面做的是什么?如果其中一个视图正在修改同一个用户,是否需要在获取用户时锁定主要托管对象上下文?从这篇文章中我理解(也许是错误的)我可能不得不这样做.到目前为止,我没有遇到任何问题,但我不想留下潜在的边缘情况.
3)当其中一个视图控制器对应用程序委托进行更改时,NSManagedObjectContext它会发布一个通知,其处理方式如下:
- (void)contextDidSave:(NSNotification *)notification {
SEL selector = @selector(mergeChangesFromContextDidSaveNotification:);
[self.logManagedObectContext performSelector:selector onThread:backgroundThread withObject:notification waitUntilDone:NO];
}
Run Code Online (Sandbox Code Playgroud)
这是我应该如何处理合并,还是我应该合并应用程序委托NSManagedObjectContext?我发现这样做(在主线程上)锁定了UI.
任何帮助将不胜感激.
NSManagedObjectContext对象不是线程安全的.这意味着如果您希望从多个线程访问Core Data,则每个线程都需要一个(并且也在线程上创建).其中每个都可以使用相同的NSPersistentStoreCoordinator,它将序列化对持久性存储的访问.
发生这种情况是因为每个人都NSManagedObjectContext 知道如何正确锁定它NSPersistentStoreCoordinator何时使用,避免碰撞.遵循这些规则,您应该保持线程安全.
正如您已经在做的那样,NSManagedObjectID应该使用对象将Core Data对象从一个MOC传递到另一个MOC(并从一个线程扩展到另一个线程).但是,您正在调用fetchUser:哪个使用主线程中的MOC,在背景上.这是不正确的.fetchUser:必须从主线程调用该方法调用.当然,没有什么可以阻止您使用后台MOC在后台线程中检索用户.
总之,始终NSManagedObjectContext从创建它的线程中调用a .
这里的诀窍是确保两个MOC都知道其他的保存,因此您必须注册以接收来自每个上下文的通知.然后,您应该mergeChangesFromContextDidSaveNotification:从MOC的相应线程执行该操作.目前,您的背景上下文正在通知主线程的上下文中的更改,但反之亦然.
哦,并没有必要为每个都有一个单独的上下文NSViewController.作为UI元素,它们与上下文的交互将发生在同一(主)线程上,因此共享很好.
| 归档时间: |
|
| 查看次数: |
1136 次 |
| 最近记录: |