如何从Core Data自动轻量级迁移切换到手动?
我的情况与这个问题类似。我正在使用轻量级使用以下代码进行迁移,来自 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有一些关于如何进行手动迁移的很好的示例,但基本步骤是:
但是,崩溃是什么?您是否因花费太长时间而被操作系统杀死?因为手动迁移并不能解决这个问题。
您使用什么类型的后备存储?如果您使用二进制文件,则可能会耗尽内存,因为迁移将在内存中拥有整个数据库的两个副本。
OP评论更新
无法在后台线程上进行迁移,因为您正在更改数据源。如果您的迁移在启动时花费的时间太长,那么推荐的解决方案是:
-applicationDidFinishLaunching:
循环完成运行循环,而无需触及核心数据。这将阻止崩溃如果您使用二进制存储,您可能仍然会遇到内存问题,但这将解决启动时的崩溃问题。崩溃是操作系统说“我认为你已经锁定了”。通过让
-applicationDidFinishLaunching:
完成,您就告诉操作系统您尚未锁定。There are good examples on how to do a manual migration but the basic steps are:
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
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:
-applicationDidFinishLaunching:
cycle through the run loop complete without ever touching Core Data. This will stop that crashIf 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.