Iphone 如何从核心数据自动轻量级迁移切换到手动?

Iphone 如何从核心数据自动轻量级迁移切换到手动?,iphone,core-data,migration,mapping-model,core-data-migration,Iphone,Core Data,Migration,Mapping Model,Core Data Migration,我的情况是,我正在使用轻量级迁移和以下代码,这些代码来自Apple docs和其他SO线程。初始化核心数据堆栈时,它在应用程序启动时运行 NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES

我的情况是,我正在使用轻量级迁移和以下代码,这些代码来自Apple docs和其他SO线程。初始化核心数据堆栈时,它在应用程序启动时运行

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文档,但我不记得有专门用于模式迁移的好例子和教程。

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

  • 创建映射模型
  • 将该映射模型包括在项目中
  • 关闭自动迁移
然而,什么是崩溃?你是否因为花太长时间而被操作系统杀死?因为手动迁移无法解决这一问题

您使用哪种类型的后备存储?如果您使用的是二进制文件,则可能会耗尽内存,因为迁移将在内存中包含整个数据库的两个副本

从OP评论更新 我想我在SQLite中也看到过这种情况,所以可能除了内存之外还有其他东西,尽管这是一个有效的观点。是的,操作系统会因为时间太长而终止它,特别是在1G设备上。我认为手动迁移也是一种从“在应用程序启动时有超时限制的情况下迁移”到没有时间限制的情况下迁移的一种方式,可以在后台线程上这样做

无法在后台线程上执行迁移,因为您正在更改数据源。如果您的迁移在启动时花费的时间太长,建议使用以下解决方案:

  • -applicationdFinishLaunching:
    在运行循环中循环完成,而不接触核心数据。这将阻止那次坠机
  • 在运行循环的下一次迭代中启动迁移(可能希望向用户显示某种进度指示器),并完成迁移

如果您使用的是二进制存储,您可能仍然会有内存问题,但这将解决启动时的崩溃问题。崩溃的原因是操作系统说“我想你已经锁定了”。通过让
-applicationdFinishLaunching:
完成,您告诉操作系统您尚未锁定。

关于如何进行手动迁移,有一些很好的示例,但基本步骤如下:

  • 创建映射模型
  • 将该映射模型包括在项目中
  • 关闭自动迁移
然而,什么是崩溃?你是否因为花太长时间而被操作系统杀死?因为手动迁移无法解决这一问题

您使用哪种类型的后备存储?如果您使用的是二进制文件,则可能会耗尽内存,因为迁移将在内存中包含整个数据库的两个副本

从OP评论更新 我想我在SQLite中也看到过这种情况,所以可能除了内存之外还有其他东西,尽管这是一个有效的观点。是的,操作系统会因为时间太长而终止它,特别是在1G设备上。我认为手动迁移也是一种从“在应用程序启动时有超时限制的情况下迁移”到没有时间限制的情况下迁移的一种方式,可以在后台线程上这样做

无法在后台线程上执行迁移,因为您正在更改数据源。如果您的迁移在启动时花费的时间太长,建议使用以下解决方案:

  • -applicationdFinishLaunching:
    在运行循环中循环完成,而不接触核心数据。这将阻止那次坠机
  • 在运行循环的下一次迭代中启动迁移(可能希望向用户显示某种进度指示器),并完成迁移

如果您使用的是二进制存储,您可能仍然会有内存问题,但这将解决启动时的崩溃问题。崩溃的原因是操作系统说“我想你已经锁定了”。通过让
-applicationdFinishLaunching:
完成,您正在告诉操作系统您尚未锁定。

我想我已经看到SQLite也发生了这种情况,因此可能除了内存之外还有其他原因,尽管这是一个有效的观点。是的,操作系统会因为时间太长而终止它,特别是在1G设备上。我认为手动迁移也是一种从“在应用程序启动时有超时限制的情况下迁移”到没有时间限制的情况下迁移的一种方式,可以在后台线程上这样做?“让-applicationdFinishLaunching:在不接触核心数据的情况下完成运行循环。”--是操作部分。我想这对于自动和手动迁移都是一样的。正确的,在这两种情况下,您都需要让应用程序的初始加载及时完成。如何解决内存问题?如何避免在内存中有两个存储区?@Kamchatka您需要创建自己的问题,因为您的评论与这个问题无关。我想我已经看到SQLite也出现了这种情况,所以可能有比内存更重要的东西,尽管这是一个正确的观点。是的,操作系统会因为时间太长而终止它,特别是在1G设备上。我认为手动迁移也是一种从“在应用程序启动时有超时限制的情况下迁移”到没有时间限制的情况下迁移的一种方式,可以在后台线程上这样做?“让-applicationdFinishLaunching:在不接触核心数据的情况下完成运行循环。”--是操作部分。我想这对于自动和手动迁移都是一样的。正确的,在这两种情况下,您都需要让应用程序的初始加载及时完成。如何解决内存问题?我怎样才能避免在内存中有两个存储?@Kamcha