gpt4 book ai didi

ios - 核心数据多线程获取记录

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:49:54 25 4
gpt4 key购买 nike

我对 CoreData 中的多线程有一个疑问。如果我们使用多线程,我们应该使用单独的 NSManagedObjectContext 来插入新数据或更新,否则我们可以使用父子上下文方法。但我只创建新的 NSManagedObjectContext。我的问题是——我是否也应该使用单独的 NSManagedObjectContext 来获取甚至在后台线程中?如果不是(即我们只能使用主队列 NSManagedObjectContext)那么为什么我会收到 __psynch_mutexwait 错误?

谢谢

最佳答案

首先,Core Data 是线程安全的。但是,您必须遵守规则:

  1. NSManagedObjectContext 是线程绑定(bind)的。您只能在分配给它的线程上使用它。 -init 导致将上下文分配给创建它的线程。使用 -initWithConcurrencyType: 将允许您创建与其他线程/队列关联的上下文。
  2. 任何与 NSManagedObjectContext 关联的 NSManagedObject 都绑定(bind)到与它来自的上下文相同的线程/队列
  3. 没有第三条规则

您可以在线程之间传递 NSManagedObjectID 实例,但必须遵守规则 1 和 2。根据您的描述,我认为您违反了这些规则。

Personally I do not recommend using NSManagedObjectID either. There are better solutions. – 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"];
}
}

注意:此代码是在网络浏览器中编写的,可能无法编译。

您检查该值是因为 -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

注意:此代码是在网络浏览器中编写的,可能无法编译。

这将错误处理和上下文/线程控制留给了开发人员,但提供了一种方便的方法来检索当前上下文中的对象,并让我们将对象从一个上下文“弹回”到另一个上下文。

这比 -objectWithID: 慢,应谨慎使用,并且仅在保存移动对象后需要将对象从一个上下文反弹到另一个上下文的情况下使用堆栈。

与我所做的大多数事情一样; 这不是通用解决方案。这是一个基线,应该根据每个项目进行调整。

关于ios - 核心数据多线程获取记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21934230/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com