Core Data托管對象模型的遷移
來自: https://segmentfault.com/a/1190000004506652
修改托管對象模型
在應用程序的進行過程中,其托管對象模型也可能需要進行修改。對于一些比較簡單的修改,諸如設定屬性的默認值、設定驗證規則、使用獲取請求模板等,是可以直接實施的。而對于另外一些更為結構化的修改,則需要把持久化存儲區遷移到新的模型版本才行。假如沒有提供遷移數據所需要的映射與設定,那么應用程序就會崩潰。
引發模型不兼容錯誤
在托管對象模型中添加另外一個新的實體,并且在新的實體中添加一些新的屬性。重新運行應用程序,你會發現程序會崩潰掉。
對于處在開發初期的應用程序來說,這種崩潰算不上什么大的問題,我們只需要吧程序刪除了并重新運行一次就好了。刪除之后,在次運行應用程序時,它會按照最新的模型來創建持久化存儲區。這樣一來,存儲區就可以和模型相兼容了,于是應用程序也就不會再次崩潰了。但是,這樣做也會失去存儲區里原有的數據。對于已經在 App Store 上架的程序來說,這讓人無法接受。有好幾種辦法都可以遷移現有的持久化存儲區,而遷移路徑則是由變更的復雜程度以及是否使用 iCloud 等因素來決定的。無論采用哪種遷移辦法,我們都必須首先熟悉“ 模型版本控制 ”。
添加模型版本
按照以下步驟來添加模型版本:
1、選中 Model.xcdatamodeld
2、點擊Editor> Add Model Version... 菜單項
3、點擊Finish,將Model2用作版本名稱。
現在項目中會有兩個版本的模型了。如圖:
Model2.xcdatamodel這個新的模型的內容一開始便與 Model.xcdatamodel 完全相同。
我們現在選中 Model2.xcdatamodel 這個新的模型,在這個新的模型中添加 Measurement 實體,創建名叫abc的屬性,并將其類型設置為String。
添加了新的版本模型之后,必須將其設置為當前版本,然后才能讓應用程序使用它。
選中 Model.xcdatamodeld 在右側將 Current Model Version 設置為Model2.如圖:
如果想正常運行應用程序,那么我們還需要配置好遷移選項,告訴Core Data應該如何去遷移。要是現在就去運行應用程序的話,那自然還是會發生Store is incompatible(存儲區不兼容)錯誤。
輕量級的遷移方式
把新的模型設置為當前版本之后,必須遷移現有的持久化存儲區,只有這樣,才能正常使用新模型。這是因為,持久化存儲區協調器會試著使用新的模型來打開原有的存儲區,但是原有的存儲區是用舊版本的模型創建的,所以會出現錯誤。在向 NSPersistentStoreCoordinator 添加存儲區的時候,只需要將下列選項放在 NSDictionary 里面傳過去,即可自動完成存儲區的遷移工作:
如果傳給 NSPersistentStoreCoordinator 的 NSMigratePersistenStoresAutomaticallyOption 是 YES ,那么Core Data 就會試著把低版本的持久化存儲區遷移到最新版本的模型。
如果傳給 NSPersistentStoreCoordinator 的 NSInferMappingModelAutomaticallyOption 是YES,那么Core Data 就會試著以最為合理地方式自動推斷出源模型實體中的某個屬性到底對應于“目標模型實體”中的哪一個屬性。
打開 CoreDataHelper.swift 同時添加一個屬性在這個類中。
lazy var options: NSDictionary?
Right now, you’re setting up the persistent store with no options for default behavior. You’ll use the options dictionary to set the necessary flags.
// 這里是添加的部分,名如其意,當我們需要自動版本遷移時,我們需要在addPersistentStoreWithType方法中設置如下options let options = [NSInferMappingModelAutomaticallyOption: true, NSMigratePersistentStoresAutomaticallyOption: true]var error: NSError? = nil persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: options, error: &error)</pre>
未完待續!
參考資料:
</div>