Core Data 的推断映射模型创建(轻量级迁移)崩溃。线程问题?
Posted
技术标签:
【中文标题】Core Data 的推断映射模型创建(轻量级迁移)崩溃。线程问题?【英文标题】:Crashes in Core Data's Inferred Mapping Model Creation (Lightweight Migration). Threading Issue? 【发布时间】:2010-03-22 00:46:02 【问题描述】:在我的应用程序中创建推断映射模型(使用 Core Data 的轻量级迁移)时,我遇到了随机崩溃。顺便说一句,我必须在我的应用程序运行时以编程方式完成它。
这就是我创建这个模型的方式(当然,在我创建了正确的 currentModel 和 newModel 对象之后):
NSMappingModel *mappingModel = [NSMappingModel inferredMappingModelForSourceModel:currentModel destinationModel:newModel error:&error];
问题是这样的:这个方法随机崩溃。当它工作时,它工作得很好,没有问题。但是当它崩溃时,它会使我的应用程序崩溃(而不是返回 nil 来表示该方法失败,因为它应该)。随机,我的意思是有时会发生,有时不会。这是不可预测的。
现在,这里是交易:我在另一个线程中运行此方法。更准确地说,它位于通过 GCD 传递以在全局主队列上运行的块内。我需要这样做,以使我的 UI 对用户来说显得清晰,即,这样我就可以在工作进行时显示进度指示器。
奇怪的事情似乎是,如果我删除 GCD 的东西并让它在主线程上运行,它似乎工作正常并且永远不会崩溃。因此,可能是因为我在另一个线程上运行它而导致崩溃?
我觉得这很奇怪,因为我不相信我违反了任何关于多线程的 Core Data 规则。特别是,我没有传递任何托管对象,并且每当我需要访问 MOC 时,我都会创建一个新的 MOC,即我不依赖任何 MOC(或者就此而言:anything) 之前在主线程上创建的。除了发生的少量 MOC 事情之外,发生在 映射模型创建方法之后,即 应用程序崩溃的点之后,因此它不可能是导致这里考虑的崩溃。
我所做的只是获取两个 MOM 并要求它们之间的映射模型。即使在线程下也不会出错,现在可以吗?
对可能发生的事情有什么想法吗?
【问题讨论】:
【参考方案1】:首先,什么是崩溃?
其次,Core Data 通常是单线程 API。您可以在多个线程中执行某些操作,但创建 NSMappingModel
很可能不是其中之一。为什么必须动态地创建映射模型?如果 MOM 是已知量,则映射也可以是已知量。
更新
首先,线程问题。 Core Data 是单线程的。但是,NSManagedObjectContext
知道如何正确锁定 NSPersistentStoreCoordinator
,因此每个线程可以有一个 NSManagedObjectContext
,因为它们知道如何正确锁定。但是,当您使用和创建映射模型时,情况并非如此。
但是,您提供的错误不是核心数据错误本身。该错误表明您试图在代码中的某处将 nil 放入集合中。在没有看到生成映射模型的代码的情况下,虽然很难猜出确切的位置。
您是否在 objc_throw_exception 处设置了断点并查看代码中的哪一行导致了此崩溃?如果它是不明显的,那么我建议您在构建映射模型时有某个点给 Core Data 一个意外的 nil。
您可以尝试的一件事是自己锁定NSPersistentStore
和/或NSManagedObjectContext
,看看是否能解决崩溃问题。但是,我怀疑当您这样做时,您将再次处理性能问题。
【讨论】:
我在此处粘贴了崩溃:pastie.org/private/jjeuc3my4kjjjiwcpqgwnw 我必须动态创建映射模型,因为 MOM 只能动态知道。但是在另一个线程中创建映射模型有什么根本错误?这其中不可能有任何东西以任何方式破坏我的数据存储。也许我需要以某种方式在主线程上创建映射模型?嗯,这让我很难避开沙滩球。 实际上,上述崩溃并不是唯一发生的崩溃类型。我见过其他两种类型。就像一开始是否发生崩溃是不可预测的一样,这 3 次崩溃中的哪一个发生也是不可预测的。我终于能够重现这两种其他类型的崩溃之一:pastie.org/private/wk33phudn48griryzdqzua【参考方案2】:我最终完全放弃了这个问题,自己创建了该死的映射模型。
【讨论】:
以上是关于Core Data 的推断映射模型创建(轻量级迁移)崩溃。线程问题?的主要内容,如果未能解决你的问题,请参考以下文章