標籤:
在coredata 資料庫結構被更改後,沒根據要求立即建立新version,而是在原version上進行了小修改,之後才想起來建立新版本。並通過以下代碼合并資料庫,
NSError *error = nil; NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,NSFileProtectionComplete, NSPersistentStoreFileProtectionKey, nil]; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); }
結果出現了Can‘t find model for source store這個 bug。我們先看看stackoverflow上的答案
Your sqlite database‘s model hash MUST match one of the mom or momd created by your xcdatamodel when you build your app. You can see the hashes in the momd‘s VersionInfo.plist in the built app‘s bundle. See below for code to find your database‘s model hash.So if you change your xcdatamodel instead of creating a new version under Xcode->Editor->Add Model Version... then your model‘s hash will be different, and addPersistentStoreWithType won‘t be able to use your old database, which used the old model. That‘s what causes the "Can‘t find model for source store" error.
我們根據這個答案去看看bundle 中的version 檔案
更改前的
再看更改後的
注意到 同樣的version 6 中的profile model 的hash值不一致,這樣就會crash。
為什麼會crash呢,因為舊版更新為新版後,documents中的資料庫是不變的,變化的是bundle中的.momd檔案加中的mom檔案和version的plist。新版本更新後,依舊會保留舊版本的mom檔案,並參照這個mom檔案來讀取舊版本資料庫,和新版本資料庫進行合并。如果舊的版本使用的mom檔案在新版本中更改了,程式就無法讀取舊版本資料,就會拋出異常。
解決方案也很簡單,找到上個版本使用的xxxx 6.xcdatamodel 檔案,替換被錯誤更改的.xcdatamodel 檔案。
iOS coredata 資料庫升級 時報Can't find model for source store