核心数据multithreading读取logging
我对coredata中的multithreading有一个疑问。 如果我们使用multithreading,我们应该使用单独的NSManagedObjectContext来插入新的数据或更新,否则我们可以使用父子上下文方法。 但是我只创build新的NSManagedObjectContext。 我的问题是,我应该使用单独的NSManagedObjectContext甚至在后台线程中获取也。 如果没有(即我们可以使用主队列NSManagedObjectContext),为什么即时获取__psynch_mutexwait错误。
谢谢,
首先,核心数据是线程安全的。 但是你必须遵守规则:
-
NSManagedObjectContext
是线程绑定的。 您只能在分配给它的线程上使用它。-init
使得上下文被分配给在其上创build的线程。 使用-initWithConcurrencyType:
将允许您创build与其他线程/队列关联的上下文。 - 与
NSManagedObject
关联的任何NSManagedObject
与其来自的上下文绑定到相同的线程/队列 - 没有第三条规则
您可以在线程之间传递NSManagedObjectID
实例,但必须遵守规则1和2。 从你的描述我相信你违反这些规则。
我个人不build议使用NSManagedObjectID。 有更好的解决scheme。 – Marcus S. Zarra
Marcus,这是我读过的Core Data线程的最简洁的解释。 使用它,因为它的介绍,有几天我仍然得到这些规则错了! 你提到“更好的解决scheme” – 你能详细说明一下吗?
我对使用NSManagedObjectID
有一个相当强烈的不信任。 在许多情况下,从一个应用程序生命周期到另一个应用程序生命周期并不一样 最初,基于文档,我们(cocoa开发人员)认为这是我们为我们创造的神话主键。 结果是不正确的。
在现代的发展与父母/孩子的情况下,景观更混乱,有一些有趣的陷阱,我们需要注意。 鉴于目前的情况,我不喜欢它比以前更多。 那么我们使用什么?
我们应该创造自己的。 它不需要太多。 如果您的数据已经没有从服务器的主键(从基于Ruby的服务器有一个id
很常见),然后创build一个。 我喜欢叫它guid
,然后有一个类似这样的-awakeFromInsert
:
- (void)awakeFromInsert { [super awakeFromInsert]; if (![self primitiveValueForKey:@"guid"]) { [self setPrimitiveValue:[[NSProcessInfo processInfo] globallyUniqueString] forKey:@"guid"]; } }
注意:这段代码是写在网页浏览器中的,可能无法编译。
您检查值,因为每个上下文调用一次-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
注意:这段代码是写在网页浏览器中的,可能无法编译。
这将error handling和上下文/线程控制留给开发者,但是提供了一种方便的方法来检索当前上下文中的对象,并让我们将对象从一个上下文“反弹”到另一个上下文。
这比-objectWithID:
慢-objectWithID:
只有在需要将对象从一个上下文反弹到另一个上下文的情况下,应该谨慎使用。
和我所做的大部分事情一样, 这不是一个通用的解决scheme 。 这是一个基准,应该根据每个项目进行调整。
- 如何从Core Data中的持久性存储中删除所有对象?
- 如何跳到detailview中的下一行
- 如何计算CoreData对象的唯一date?
- Swift + CoreData:无法在NSManagedObject子类上设置Bool – Bug?
- 如果我的已发行v1版本没有版本化的核心数据模型,我可以使用“自动轻量级迁移”吗?
- 如果语句失败与CoreData托pipe对象的variables
- iOS的崩溃'NSInternalInconsistencyException',原因:'语句仍然是'核心数据caching相关?
- RestKit:映射JSONstring数组
- 从不同的viewControllers中填充一个CoreData实体