小结CoreData的Migration

本文介绍如何处理CoreData中Entity、Property或Relationship变更导致的问题。包括轻量级迁移、重命名实体及属性的方法,以及如何使用自动迁移选项进行数据兼容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

   
  1. if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl   
  2.                         options:nil error:&error]) {  
  3.         // Update to handle the error appropriately.  
  4.         NSLog(@"[persistentStoreCoordinator] Unresolved error %@, %@", error, [error userInfo]);  
  5.         exit(-1);  // Fail  
  6.     }  

这个问题容易理解,我们就是通过一个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失败后抛出异常,也可以改成其他的错误返回,也可以使用CoreData的迁移(Migration)来兼容旧的数据,下面介绍一下迁移的方法

如果CoreData的实体数据发生下面几种变化的情况:

  • 增加一个属性
  • 必选的(non-optional)属性变成可选的(optional)
  • 可选的(optional)属性变成了必选的(non-optional),并且定义了默认值

可以通过简单的方法(轻量级迁移)使得我们可以直接使用新的mom文件来访问旧的sqlite文件,既在打开存储文件的之前打开自动迁移:

  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文件之后,打开存储文件之前调用如下代码:

    NSEntityDescription *automobile = [[destinationModel entitiesByName] objectForKey:@"Automobile"];
    [automobile setRenamingIdentifier:@"Car"];
    NSPropertyDescription *paintColor = [[automobile attributesByName] objectForKey:@"paintColor"];
    [paintColor setRenamingIdentifier:@"color"];

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

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

    • 默认迁移
    • 自定义迁移

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

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

    原文地址

内容概要:本文档为《400_IB Specification Vol 2-Release-2.0-Final-2025-07-31.pdf》,主要描述了InfiniBand架构2.0版本的物理层规范。文档详细规定了链路初始化、配置与训练流程,包括但不限于传输序列(TS1、TS2、TS3)、链路去偏斜、波特率、前向纠错(FEC)支持、链路速度协商及扩展速度选项等。此外,还介绍了链路状态机的不同状态(如禁用、轮询、配置等),以及各状态下应遵循的规则和命令。针对不同数据速率(从SDR到XDR)的链路格式化规则也有详细说明,确保数据包格式和控制符号在多条物理通道上的一致性和正确性。文档还涵盖了链路性能监控和错误检测机制。 适用人群:适用于从事网络硬件设计、开发及维护的技术人员,尤其是那些需要深入了解InfiniBand物理层细节的专业人士。 使用场景及目标:① 设计和实现支持多种数据速率和编码方式的InfiniBand设备;② 开发链路初始化和训练算法,确保链路两端设备能够正确配置并优化通信质量;③ 实现链路性能监控和错误检测,提高系统的可靠性和稳定性。 其他说明:本文档属于InfiniBand贸易协会所有,为专有信息,仅供内部参考和技术交流使用。文档内容详尽,对于理解和实施InfiniBand接口具有重要指导意义。读者应结合相关背景资料进行学习,以确保正确理解和应用规范中的各项技术要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值