核心数据版本控制(轻量级迁移)问题

Posted

技术标签:

【中文标题】核心数据版本控制(轻量级迁移)问题【英文标题】:Core data Versioning (Lightweight migration) Issue 【发布时间】:2015-01-28 14:04:01 【问题描述】:

我在我的应用程序中使用核心数据,它的第一个版本于 10 月发布。然后我对数据模型进行了一些更改并上传了下一个版本。它开始在现有用户的设备上崩溃(启动时崩溃),但是当他们重新安装它或新用户下载它时它运行正常。 然后我了解了版本控制并创建了一个新版本,即 1.1,并在应用程序委托中添加了以下代码行

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
if (_persistentStoreCoordinator != nil) 
    return _persistentStoreCoordinator;


NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"golfCourse.sqlite"];

NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

NSDictionary *options = @
                          NSMigratePersistentStoresAutomaticallyOption : @YES,
                          NSInferMappingModelAutomaticallyOption : @YES
                          ;

if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) 
    /*
     Replace this implementation with code to handle the error appropriately.

     abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

     Typical reasons for an error here include:
     * The persistent store is not accessible;
     * The schema for the persistent store is incompatible with current managed object model.
     Check the error message to determine what the actual problem was.


     If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.

     If you encounter schema incompatibility errors during development, you can reduce their frequency by:
     * Simply deleting the existing store:
     [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]

     * Performing automatic lightweight migration by passing the following dictionary as the options parameter:
     @NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES

     Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.

     */
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

    abort();


return _persistentStoreCoordinator;

我在模拟器和 iphone 上对此进行了测试,它工作正常,但是当我上传它时。对于现有应用用户,它在启动时再次崩溃。

iTunes 上没有崩溃日志。

为了测试这个问题,我创建了另一个版本的数据模型并遵循了这个 approach 测试模型版本。 它工作正常。 应用程序在启动时崩溃,所以我猜数据模型的变化是原因。但我不确定为什么在添加适当的选项(轻量级迁移)后它会崩溃。

【问题讨论】:

从你的 appdelegate 添加一个带有“managedObjectModel”的部分,你是如何得到这个的。 添加的代码请检查 您是否创建了模型的版本? 看不到任何有问题的更改。确保你得到合并模型,我使用NSManagedObjectModel.mergedModelFromBundles(nil)! 它是 Swift 但在 obj-c 中有相同的方法。 在你使用[self managedObjectModel]的代码中,请向我们展示这个getter的实现。 【参考方案1】:

您是否有反映您所做更改的新版本模型?或者您刚刚在一个独特的 xcdatamodeld 文件中完成了更改? 要创建新的模型版本:

    选择您的 xcdatamodel 文件 编辑器->添加模型版本 再次选择您的 xcdatamodel 文件,在右侧面板中找到模型版本并将当前设置为您刚刚创建的模型

查看https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmModelFormat.html#//apple_ref/doc/uid/TP40004399-CH3-SW1

【讨论】:

我创建了一个新版本1.1(一个新模型),然后在新版本中添加了一些属性。

以上是关于核心数据版本控制(轻量级迁移)问题的主要内容,如果未能解决你的问题,请参考以下文章

核心数据版本控制 - 需要多个映射模型

核心数据:何时启用轻量级迁移?

核心数据版本控制和迁移

核心数据模型版本控制和数据迁移

核心数据版本控制,总是加载以前的版本

核心数据轻量级迁移 - 何时版本?