Realm迁移失败:Migration required报错且迁移块未执行求助
解决Realm迁移块不执行、仍提示"Migration is required"的问题
我之前也踩过Realm迁移的同款坑,太懂这种明明按文档做了却报错的憋屈感!咱们来一步步揪出问题所在:
1. 确保Realm配置全局生效且初始化时机正确
这是最容易踩的坑:很多人会在某个ViewController或者工具类里单独创建配置,但其他访问Realm的地方用了默认配置,导致迁移块根本没被加载。
正确做法:在App启动的最早时机(比如application:didFinishLaunchingWithOptions:)设置全局默认配置,并且在任何Realm操作前完成这个设置:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 获取默认配置 RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; // 递增schema版本号(必须比之前的版本高) config.schemaVersion = 2; // 编写迁移逻辑 config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) { // 只处理旧版本低于当前版本的情况 if (oldSchemaVersion < 2) { // 情况1:将原NSString类型的regDate改为NSDate [migration enumerateObjects:Track.className block:^(RLMObject *oldObject, RLMObject *newObject) { // 根据你实际的日期字符串格式转换,这里只是示例 NSString *oldDateStr = oldObject[@"regDate"]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss"; newObject[@"regDate"] = [formatter dateFromString:oldDateStr]; }]; // 情况2:新增n_regDate属性(如果是这种需求的话) // [migration enumerateObjects:Track.className block:^(RLMObject *oldObject, RLMObject *newObject) { // // 可以给新属性设置默认值,或者从旧属性转换 // newObject[@"n_regDate"] = [NSDate date]; // }]; } }; // 设置为全局默认配置 [RLMRealmConfiguration setDefaultConfiguration:config]; // 提前触发Realm初始化,强制执行迁移(可选但推荐) NSError *error = nil; [RLMRealm defaultRealmWithError:&error]; if (error) { NSLog(@"Realm初始化失败:%@", error); } return YES; }
2. 清理残留的旧Realm文件
有时候模拟器/真机里的旧Realm文件没有被替换,导致schema版本不匹配。可以:
- 模拟器:删除App后重新运行,或者用Xcode的
Product -> Clean Build Folder清理缓存 - 真机:卸载App后重装
- 调试时可以临时用代码删除旧文件(注意上线前要移除这段代码):
// 调试用:删除旧Realm文件 NSString *realmPath = [RLMRealmConfiguration defaultConfiguration].fileURL.path; if ([[NSFileManager defaultManager] fileExistsAtPath:realmPath]) { [[NSFileManager defaultManager] removeItemAtPath:realmPath error:nil]; }
3. 检查模型类的属性定义是否正确
- 如果是修改
regDate的类型:确保Track.h里的定义是@property (nonatomic, strong) NSDate *regDate;,Track.m里加上@dynamic regDate;(Objective-C环境) - 如果是新增
n_regDate:确保模型类里已经添加了对应的属性定义,并且没有拼写错误 - 还要检查代码中是否有其他地方还在给
regDate赋值NSString类型,这也会导致迁移后的报错
4. 确认schemaVersion的正确性
- 版本号必须严格递增,不能重复或降低(比如之前用了版本2,现在修改模型就要用版本3)
- 可以打印当前Realm文件的实际版本号,确认是否和你设置的一致:
RLMRealm *realm = [RLMRealm defaultRealm]; NSLog(@"当前Realm文件版本:%llu", realm.configuration.schemaVersion);
5. 迁移块逻辑要覆盖所有旧版本
确保迁移块里的条件判断能覆盖到所有需要迁移的旧版本,比如如果你的版本从1升到2,if (oldSchemaVersion < 2)就会执行迁移逻辑;如果是从0升到2,这个条件也能正确触发。
内容的提问来源于stack exchange,提问作者Baroque Code
相关产品推荐
相关产品推荐

