Core data multithreading fetch record
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Core data multithreading fetch record相关的知识,希望对你有一定的参考价值。
我对CoreData中的多线程有一个疑问。如果使用多线程,则应使用单独的NSManagedObjectContext来插入新数据或进行更新,否则我们可以使用父子上下文方法。但是我仅创建新的NSManagedObjectContext。我的问题是-即使在后台线程中,我也应该使用单独的NSManagedObjectContext进行提取吗?如果不是(即我们只能使用主队列NSManagedObjectContext),那为什么我会收到__psynch_mutexwait错误?
谢谢
首先,核心数据是线程安全的。但是,您必须遵循以下规则:
NSManagedObjectContext
是线程绑定的。您只能在分配给它的线程上使用它。-init
导致将上下文分配给在其上创建的线程。使用-initWithConcurrencyType:
将允许您创建与其他线程/队列关联的上下文。- 与
NSManagedObject
相关联的任何NSManagedObjectContext
与其上下文来自相同的线程/队列 - 没有第三条规则
您可以在线程之间传递NSManagedObjectID
实例,但必须遵守规则1和2。根据您的描述,我认为您违反了这些规则。
我个人也不建议使用NSManagedObjectID。有更好的解决方案。 – Marcus S. Zarra
Marcus,这是我读过的关于Core Data线程的最简洁的解释。自从引入以来就使用了它,有时候我仍然会误解这些规则!您提到“更好的解决方案”-您能详细说明吗?
我对NSManagedObjectID
的使用非常不信任。在许多情况下,从一个应用程序生命周期到另一个应用程序生命周期并不相同。最初,基于文档,我们(一般为Cocoa开发人员)认为这是为我们生成的神话般的主键。事实证明这是不正确的。
在具有父/子上下文的现代开发中,环境更加令人困惑,我们需要注意一些有趣的陷阱。考虑到当前的形势,我比以前更不喜欢它。那我们用什么呢?
我们应该产生我们自己的。不需要太多。如果您的数据还没有来自服务器的主键(从基于Ruby的服务器获得id
很常见),则创建一个。我喜欢称它为guid
,然后有一个类似于此的-awakeFromInsert
:
- (void)awakeFromInsert
[super awakeFromInsert];
if (![self primitiveValueForKey:@"guid"])
[self setPrimitiveValue:[[NSProcessInfo processInfo] globallyUniqueString] forKey:@"guid"];
[注:此代码是在Web浏览器中编写的,可能无法编译。
您检查该值是因为每个上下文都调用了-awakeFromInsert
。然后,通常在NSManagedObject
实例上将有一个便捷方法,类似于:
@implementation MyManagedObject
+ (MyManagedObject*)managedObjectForGUID:(NSString*)guid inManagedObjectContext:(NSManagedObjectContext*)context withError:(NSError**)error
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:[self entityName]];
[fetch setPredicate:[NSPredicate predicateWithFormat:@"guid == %@", guid]];
NSArray *results = [context executeFetchRequest:request error:error];
if (!results) return nil;
return [results lastObject];
@end
[注:此代码是在Web浏览器中编写的,可能无法编译。
这将错误处理和上下文/线程控制留给开发人员,但提供了一种方便的方法来检索当前上下文上的对象,并让我们将一个对象从一个上下文“反弹”到另一个上下文。
这比-objectWithID:
慢,并且应谨慎使用,并且仅在以下情况下需要使用:将对象从一个上下文反弹到另一个上下文,然后将其移动到堆栈中。
与我所做的大多数事情一样; 这不是通用解决方案
。这是一个基线,应根据每个项目进行调整。以上是关于Core data multithreading fetch record的主要内容,如果未能解决你的问题,请参考以下文章
MIT6.S081-Lab6 Lab Multithreading