如何从Core Data自动轻量级迁移切换到手动?

发布于 2024-08-29 08:02:49 字数 1114 浏览 3 评论 0原文

我的情况与这个问题类似。我正在使用轻量级使用以下代码进行迁移,来自 Apple 文档和其他 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
}

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

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

My situation is similar to this question. I am using lightweight migration with the following code, fairly vanilla from Apple docs and other SO threads. It runs upon app startup when initializing the Core Data stack.

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
}

For some users, especially with slower devices, I have crashes confirmed by logs at the indicated line.

I understand that a fix is to switch this to manual mapping and migration. What is the recipe to do that? The long way for me would be to go through all Apple docs, but I don't recall there being good examples and tutorials specifically for schema migration.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尤怨 2024-09-05 08:02:49

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

  • 创建一个映射模型
  • ,在项目中包含该映射模型
  • 关闭自动迁移

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

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

OP评论更新

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

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

  • -applicationDidFinishLaunching: 循环完成运行循环,而无需触及核心数据。这将阻止崩溃
  • 通过运行循环在下一次迭代中启动迁移(可能想要向用户呈现某种进度指示器)并完成迁移。

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

There are good examples on how to do a manual migration but the basic steps are:

  • create a mapping model
  • include that mapping model with your project
  • turn off automigration

However, what is the crash? Are you being killed by the OS for taking too long? As a manual migration will not cure that.

What type of backing store are you using? If you are using binary it is possible to blow out memory because a migration will have two copies of the entire database in memory.

update from OP comment

I think I have seen this happen also with SQLite, so maybe there is something more than memory, although that is a valid point. Yes, it is killed by OS for taking too long, especially on 1G devices. I thought that manual migration was also a way to move from "migrate on app startup which has timeout constraints" to something which has no time constraints, and do it maybe on background thread or such. ?

There is no way to do the migration on a background thread because you are changing the source of the data. If your migration is taking too long on start up then the recommended solution is:

  • Let the -applicationDidFinishLaunching: cycle through the run loop complete without ever touching Core Data. This will stop that crash
  • Kick off the migration on the next iteration through the run loop (probably want to present some kind of progress indicator to the user) and complete the migration.

If you are using a binary store you are probably still going to have memory issues, but this will solve your crash on launch. The crash is the OS saying "I think you have locked up". By letting the -applicationDidFinishLaunching: complete you are telling the OS that you have not locked up.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文