NSLog(@"MOC save error : %@", error);
}
}
版本遷移
CoreData版本遷移的方式有很多,一般都是先在Xcode中,原有模型文件的基礎(chǔ)上,創(chuàng)建一個新版本的模型文件,然后在此基礎(chǔ)上做不同方式的版本遷移。
本章節(jié)將會講三種不同的版本遷移方案,但都不會講太深,都是從使用的角度講起,可以滿足大多數(shù)版本遷移的需求。
為什么要版本遷移?
在已經(jīng)運行程序并通過模型文件生成數(shù)據(jù)庫后,再對模型文件進(jìn)行的修改,如果只是修改已有實體屬性的默認(rèn)值、最大最小值、Fetch Request等屬性自身包含的參數(shù)時,并不會發(fā)生錯誤。如果修改模型文件的結(jié)構(gòu),或修改屬性名、實體名等,造成模型文件的結(jié)構(gòu)發(fā)生改變,這樣再次運行程序就會導(dǎo)致崩潰。
在開發(fā)測試過程中,可以直接將原有程序卸載就可以解決這個問題,但是本地之前存儲的數(shù)據(jù)也會消失。如果是線上程序,就涉及到版本遷移的問題,否則會導(dǎo)致崩潰,并提示如下錯誤:
CoreData: error: Illegal attempt to save to a file that was never opened. "This NSPersistentStoreCoordinator has no persistent stores (unknown). It cannot perform a save operation.". No last error recorded.
然而在需求不斷變化的過程中,后續(xù)版本肯定會對原有的模型文件進(jìn)行修改,這時就需要用到版本遷移的技術(shù),下面開始講版本遷移的方案。
創(chuàng)建新版本模型文件
本文中講的幾種版本遷移方案,在遷移之前都需要對原有的模型文件創(chuàng)建新版本。
選中需要做遷移的模型文件 -> 點擊菜單欄Editor -> Add Model Version -> 選擇基于哪個版本的模型文件(一般都是選擇目前最新的版本),新建模型文件完成。
對于新版本模型文件的命名,我在創(chuàng)建新版本模型文件時,一般會拿當(dāng)前工程版本號當(dāng)做后綴,這樣在模型文件版本比較多的時候,就可以很容易將模型文件版本和工程版本對應(yīng)起來。

創(chuàng)建新版本模型文件
添加完成后,會發(fā)現(xiàn)之前的模型文件會變成一個文件夾,里面包含著多個模型文件。

模型文件夾
在新建的模型文件中,里面的文件結(jié)構(gòu)和之前的文件結(jié)構(gòu)相同。后續(xù)的修改都應(yīng)該在新的模型文件上,之前的模型文件不要再動了,在修改完模型文件后,記得更新對應(yīng)的模型類文件。
基于新的模型文件,對Employee實體做如下修改,下面的版本遷移也以此為例。

修改之前
添加一個String類型的屬性,設(shè)置屬性名為sectionName。

修改之后
此時還應(yīng)該選中模型文件,設(shè)置當(dāng)前模型文件的版本。這里選擇將最新版本設(shè)置為剛才新建的1.1.0版本,模型文件設(shè)置工作完成。
Show The File Inspector -> Model Version -> Current 設(shè)置為最新版本。

設(shè)置版本
對模型文件的設(shè)置已經(jīng)完成了,接下來系統(tǒng)還要知道我們想要怎樣遷移數(shù)據(jù)。在遷移過程中可能會存在多種可能,蘋果將這個靈活性留給了我們完成。剩下要做的就是編寫遷移方案以及細(xì)節(jié)的代碼。
輕量級版本遷移
輕量級版本遷移方案非常簡單,大多數(shù)遷移工作都是由系統(tǒng)完成的,只需要告訴系統(tǒng)遷移方式即可。在持久化存儲協(xié)調(diào)器(PSC)初始化對應(yīng)的持久化存儲(NSPersistentStore)對象時,設(shè)置options參數(shù)即可,參數(shù)是一個字典。PSC會根據(jù)傳入的字典,自動推斷版本遷移的過程。
字典中設(shè)置的key:
NSMigratePersistentStoresAutomaticallyOption設(shè)置為YES,CoreData會試著把低版本的持久化存儲區(qū)遷移到最新版本的模型文件。
NSInferMappingModelAutomaticallyOption設(shè)置為YES,CoreData會試著以最為合理地方式自動推斷出源模型文件的實體中,某個屬性到底對應(yīng)于目標(biāo)模型文件實體中的哪一個屬性。