CoreData Migration

当CoreData中的Entity,Property或者Relationship发生改变以后,默认情况下面,在尝试调用CoreData的时候,程序会异常退出,具体是在:

if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])

 {

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

        abort();//出错

    }    

myCoreData[4100:c07] Unresolved error Error Domain=NSCocoaErrorDomain Code=134100 "The operation couldn’t be completed. (Cocoa error 134100.)"

这个问题容易理解,我们就是通过一个ManagerdObjectModel(具体对应xcode里面的xxx.xcdatamodel文件,下面简称mom)来访问具体的存储数据,这里是xxx.sqlite文件,mom有一个hash table保存这个sqlite文件中的所有数据类型,版本等,当发现不匹配了就返回错误,如果想简单起见,可以在这里删除旧的数据,重新load一遍。

但是这样子可能会造成不必要的麻烦,因为你之前存储的数据也一并被删除了,所以需要寻求别的方法。

  1. if(![fileManager removeItemAtPath:storePath error:&error]){  

  2.             [NSException raise:NSInternalInconsistencyException format:@"Failed to remove ecrupt sqlite file. Location:%@", NSStringFromSelector(_cmd)];  

  3.         }  

  4.           

  5.         NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"im" ofType:@"sqlite"];  

  6.         if (defaultStorePath) {  

  7.             [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];  

  8.         }     

  9.           

  10.         if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl   

  11.                                                             options:options error:&error]){  

  12.             [NSException raise:NSInternalInconsistencyException format:@"Failed to addPersistentStoreWithType. Location:%@", NSStringFromSelector(_cmd)];  

  13.         } 

这里在第二次add失败后抛出异常,也可以改成其他的错误返回

  1. NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],   

  2.                              NSMigratePersistentStoresAutomaticallyOption,   

  3.                                                          [NSNumber numberWithBool:YES],   

  4.                              NSInferMappingModelAutomaticallyOption, nil];    

  5.    

  6.     NSError *error;  

  7.     if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType   

  8.                                                       configuration:nil   

  9.                                                                 URL:storeUrl   

  10.                                         options:options error:&error]) {  

  11.         // Update to handle the error appropriately.  

  12.         exit(-1);  // Fail  

  13.     }  

除了上面的修改,还需要版本化xxx.xcdatamodel文件,在Xcode3.2上是在Design-Data Modal-Add Model Version,在新的xcdatamodal文件中修改,并设置为当前版本(在Design-Data Modal-Set Current Version)

最后一步,需要指定使用新的xcdatamodal文件:

[cpp]      view plain     copy    

  1. - (NSManagedObjectModel *)managedObjectModel {  

  2.       

  3.     if (managedObjectModel != nil) {  

  4.         return managedObjectModel;  

  5.     }  

  6.   

  7.   

  8.     NSString *path = [[NSBundle mainBundle] pathForResource:@"xxx 2" ofType:@"mom" inDirectory:@"xxx.momd"];  

  9.     NSURL *momURL = [NSURL fileURLWithPath:path];  

  10.       

  11.     return managedObjectModel;  

  12. }  



上述代码指定使用xxx 2.xcdatamodel初始化mom文件注:这一步不确定是否是必须的,似乎用一下代码也可以:

[cpp]      view plain     copy    

  1. - (NSManagedObjectModel *)managedObjectModel {  

  2.       

  3.     if (managedObjectModel != nil) {  

  4.         return managedObjectModel;  

  5.     }  

  6.   

  7.   

  8.     NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"xxx" withExtension:@"momd"];  

  9.     managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];      

  10.       

  11.     return managedObjectModel;  

  12. }  


 


另外,还有一种情况

  • 重命名了实体或者属性

    需要在加载mom文件之后,打开存储文件之前调用如下代码:

     automobile  destinationModel entitiesByName objectForKey;automobile setRenamingIdentifier; paintColor  automobile attributesByName objectForKey;paintColor setRenamingIdentifier;

       

    或者可以直接在mom编辑器里面设置,请参考

    其他的变化我们需要使用Mapping的机制来完成数据的迁移,这里有两种方式可以选择(参考):

    默认迁移只需要做两步,第一步在前面已经做过了,就是在轻量级迁移中设置的参数,第二步需要一个map文件,生成方法可以参考,如果不生成该文件,在访问存储文件时成功,但在访问数据的时候会发生异常;


    自定义迁移需要手动控制各个实体,字段的迁移方式,我还没有试过

    • 默认迁移

    • 自定义迁移

转载于:https://my.oschina.net/starmier/blog/186041

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值