0

我的情况与这个问题类似。我正在使用带有以下代码的轻量级迁移,来自 Apple 文档和其他 SO 线程的相当普通的。它在初始化 Core Data 堆栈时在应用程序启动时运行。

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
    nil];

NSError *error = nil;

NSString *storeType = nil;
if (USE_SQLITE) { // app configuration
    storeType = NSSQLiteStoreType;
} else {
    storeType = NSBinaryStoreType;
}

persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

// the following line sometimes crashes on app startup
if (![persistentStoreCoordinator addPersistentStoreWithType:storeType configuration:nil URL:[self persistentStoreURL] options:options error:&error]) {
    // handle the error
}

对于某些用户,尤其是使用速度较慢的设备的用户,我在指示行的日志中确认了崩溃。

我知道解决方法是将其切换为手动映射和迁移。这样做的秘诀是什么?对我来说,很长的路要走所有 Apple 文档,但我不记得有专门用于模式迁移的好的示例和教程。

4

1 回答 1

3

关于如何进行手动迁移有很好的例子,但基本步骤是:

  • 创建映射模型
  • 将该映射模型包含在您的项目中
  • 关闭自动迁移

然而,什么是崩溃?您是否因花费太长时间而被操作系统杀死?因为手动迁移无法解决这个问题。

您使用的是什么类型的后备存储?如果您使用二进制,则可能会耗尽内存,因为迁移将在内存中拥有整个数据库的两个副本。

从 OP 评论更新

我想我已经看到 SQLite 也发生了这种情况,所以也许有比内存更多的东西,尽管这是一个有效的观点。是的,它会因为耗时太长而被操作系统杀死,尤其是在 1G 设备上。我认为手动迁移也是一种从“在具有超时限制的应用程序启动时迁移”到没有时间限制的迁移的方法,并且可能在后台线程等上进行。?

无法在后台线程上进行迁移,因为您正在更改数据源。如果您的迁移启动时间过长,那么推荐的解决方案是:

  • 让整个-applicationDidFinishLaunching:运行循环的循环完成,而无需接触核心数据。这将停止崩溃
  • 通过运行循环在下一次迭代中开始迁移(可能希望向用户呈现某种进度指示器)并完成迁移。

如果您使用的是二进制存储,您可能仍然会遇到内存问题,但这将解决您在启动时的崩溃问题。崩溃是操作系统说“我认为你已锁定”。通过让-applicationDidFinishLaunching:完整,您告诉操作系统您没有锁定。

于 2010-04-16T16:37:01.817 回答