原文出處: informit 譯文出處:cocoachina html
Core Data是蘋果針對Mac和iOS平臺開發的一個框架,主要用來儲存數據。對不少開發者來講,Core Data比較容易入手,但很難精通,若是沒有正確的學習方法,你將很難真正理解它,更不用說精通了。不少開發者經常在這方面犯一些錯誤,而這篇文章列出了開發者在iOS開發過程當中使用Core Data常見的一些錯誤,並對如何避免這些錯誤進行了分析。ios
1.不瞭解關鍵術語數據庫
對於iOS開發者來講,會使用Core Data是一項必備技能。 沒有它,不少app都不會存在。當在互聯網上四處搜索Core Data學習教程,你很容易被各類各樣的術語嚇倒。事實上大部分學習教程都首先假定你已經知道了這些術語,而若是你不瞭解這些術語,那將會陷入困惑中。因此首先要知道關鍵的術語。這裏有一個備忘單,能夠用在學習Core Data的過程當中,這份備忘單展現了關鍵的詞組:
網絡
在之後的學習過程當中,你會遇到更多的術語,但這些是初學者須要瞭解的最基本的部分。app
2.徹底忽視Core Data框架
當一項技術以難學「聞名」時,你可能會忽略它,特別是當你時間不夠,急着把app作出來的時候。ide
Core Data儲存app數據的一個常見替代選擇是使用XML屬性列表,雖然屬性列表可讓你今天的工做變得輕鬆,但它們也會隨後回過頭來咬你一口。不管什麼時候你編輯屬性列表,發生的變化都是原子性的。這意味着即使是很小的更改要求,整個文件都會被加載到內存中,而後在保存的時候,整個文件都會被寫回到硬盤。性能
隨着數據量的增加,app也會變得愈來愈慢。可是若是你基於SQLite數據庫使用Core Data時,這些性能問題就不會困擾你 。這樣能夠保持低內存佔用,以保證app快速響應,並防止app因內存壓力過大而崩潰。本質上說,Core Data之因此比屬性類表更有擴展性的緣由是它支持使用數據庫進行持久性儲存。可擴展性並非Core Data的惟一優點,使用關係把數據組織進實體結構纔是其強大之處。好比,考慮使用如下實體來表明一個任務 :
學習
該任務實體包含一個名稱和subtask_name屬性。當從任務實體中建立管理對象時,它將會有一個名稱和subtask_name屬性。測試
不依賴關係,這個數據模型僅支持一個subtask,如今考慮如下實體:
帶有雙箭頭的線代表Task entity能夠對應多個Subtask entity關係,這意味着一個任務能夠有多個子任務,更沒必要說涉及到的父任務也能經過逆關係被包含進來。這個靈活性不只方便,更節省了數據庫的空間,由於父任務名稱僅僅只需儲存一次。若是你想要更進一步,讓任務有子任務的子任務,下一步該怎麼辦?思考下從新構建如下任務實體:
模型如今支持無線深度的子任務,由於任務實體關聯的是其自己!Core Data的可擴展性和靈活性還只是其優點中不多的一部分。Core Data並不只僅利用關係數據庫的優點,並且你沒必要寫任何SQL語句來使用它。Core Data替你承擔了責任,而且爲你自動優化了生成的SQL語句。
我尚未深刻研究Core Data的其餘價值方面,好比模型版本控制、遷移、驗證以及變動管理和iCloud同步等等。若是有任何值得你投入時間的iOS框架,那就是Core Data。
3. 不使用模型版本控制和遷移
若是你已經編輯了一個管理對象模型,你可能已經犯了如下錯誤:
「此前用來打開store的模型不兼容之前用來建立store的模型」
當你建立數據持久化存儲,它是基於一個特定的管理對象模型的。若是模型的結構發生了變化,那麼持久化存儲就必須更新以匹配。若是不這麼作,store將會是不兼容的,而且不能打開。若是用戶正使用的存儲是基於你的沒有使用版本控制的模型,那麼app註定會崩潰。
爲了確保模型遷移過程正常進行,你須要確保你在編輯模型前很是當心地添加了模型版本。
附註:一些變化,好比屬性默認、有效性規則以及獲取請求模板均可以被簡化。
4.過多使用版本控制和遷移
一旦開發者瞭解到維持管理對象模型版本的簡易,一些開發者難免會過度使用。這會產生一個過度複雜化的版本歷史記錄,若是每次更改都添加版本,這隻會減緩模型的遷移。
在你發佈Core Data app到App Store以前,你能夠忽略版本控制,並按你喜歡的那樣編輯模型。爲避免「the store is incompatible」錯誤,能夠簡單地從開發設備上刪除app,並再次在Xcode中運行。使用更新的模型部署一個新的持久化儲存,就能夠解決崩潰問題。一旦你把model version 1發佈到App Store,你全部的用戶將會有version 1的持久化存儲。從這一點上來講,若是更新模型則必須添加一個新版本。咱們假定你的用戶正使用model version 1。當開發一個更新版的app,你已經添加了model versions 2, 3和4。使用如下小技巧能夠減小版本歷史,而不用發佈model versions 2, 3,4…
刪除model 2的內容
複製model 4內容至model 2
設置model 2爲當前model
刪除model 4
固然,你須要考慮model 1中的實體如何映射到更重要的model 2中,尤爲在你沒有使用輕量級遷移時。更加詳細的關於model版本控制和遷移,可查看「Learning Core Data for iOS」這一個完整章節。
5.把一切留在內存中
你主要關注功能和特性,因此你很容易忘記那些不那麼迷人的主題,好比保持低內存佔用。有些開發者會在進行性能測試前急匆匆地發佈應用,尤爲是截止期限所迫的狀況下。不過還好咱們仍有一些措施幫你保持低內存佔用。
當你管理對象時,在內存方面可以使用管理對象context。一旦你完成了管理對象,你應該經過調用如下NSManagedObjectContext實例方法之一來移除它們。
經過重置來從context中移除全部管理對象。
使用refreshObject:mergeChanges並傳入參數NO 從context中移除特定的對象。
使用以上任意一個方法能夠確保未使用的對象沒有浪費空間。爲了在context中提升對象數目的可見性,可記錄[[context registeredObjects] count]結果以方便在控制檯中調試。
6.設計一個低質量的Managed Object Model
若是你儲存照片、音頻或者視頻,你在模型設計上要十分當心。記住關鍵的一點是當你把managed object帶入context時,你正把全部數據一併帶入內存中。例如,若是一個managed object帶有一個圖像屬性,該屬性存儲了一張很大的圖片,同時一個表格視圖使用它來建立衆多實體對象並填充單元格, 那麼app性能就會受到影響。即時你使用一個得到結果的控制器,你仍須要一次加載不少高分率的圖片,這個操做不會馬上執行。爲了解決這一問題,持有大量對象的屬性應該被分裂進一個關聯實體。按照這個方法,大量對象能夠被持久化存儲。若是你須要在table view中展現照片,你應該使用自動生成縮略圖代替。
7.不提早加載數據
當你把模型加載進一個更新的app時,要注意不要意外地加載一個基於舊模型的默認數據存儲。若是你這麼作了,那麼對一些用戶來講,可能會在運行應用的時候致使崩潰。這個威脅能夠從根本上阻止開發者加載一個默認的數據存儲。
若是有默認數據包含在app中,那app就更容易學習和使用了。一個程序越容易使用,那麼用戶就越有可能繼續使用它。用戶使用一款應用的時間越長,那麼用戶傳播它的機會就越大,最後也會提高應用潛在的銷售狀況。爲了不在提供默認數據的狀況下出現的更新時崩潰現象,你須要一個好的測試策略。
另外,你也須要深入、準確地理解你想把什麼樣的模型版本和存儲發佈到App Store。你應該部署一個未改變的App Store應用版本到你的設備上,添加數據,而後完全測試升級進程。
8.只使用單一的Contexts
Core Data的實現至少須要一個context 在主線程上操做。用戶接口也需運行在主線程,所以任何減緩主線程的行爲都會下降程序的響應能力。雖然使用一個context很是容易,可是性能問題會悄然出現,除非你的數據設置很是小。好比,若是你想要生成數據縮略圖,或者導入一些數據,app就會這些過程當中出現阻塞現象。
自從iOS 5之後,管理多個context已經變得很是容易了。如今你能夠配置一個context 層級,並在前臺和後臺運行一些contexts。經過配置後臺context做爲前臺 context的父類,你就能夠實現後臺保存。經過配置後臺context做爲前臺context的子類,你就能夠像導入對象同樣導入context來自動更新用戶接口.
9.不理解iCloud Integration的侷限性
iOS 7發佈之後 ,Core Data集成iCloud的實現變得更加簡單。iCloud一個關鍵性的限制是它的數據被約束在一個iCloud帳戶中。因爲iCloud帳戶是與用戶設備的方方面面交錯在一塊兒,因此分享iCloud帳戶是不切實際的,不推薦的。這意味着iCloud 不能被用來共享。好比,假定一位丈夫和妻子想要在同一個購物列表上列出物品,這一點當前對iCloud來講也是不可能的。
除了帳號限制,iCloud也不支持ordered relationships,也限制你的輕量級的model遷移。跳出這個圈子思考,若是你對app使用的收集分析統計比較感興趣,你能夠考慮使用Backend-as-a-Service (BaaS)。
10.不考慮現有的客戶數據集成iCloud
在iOS 7中,iCloud集成Core Data已經容易了不少,不少開發者有信心在應用中支持它,此前用它來託管珍貴的用戶數據並不穩定。這致使了不少現有的app僅有本地儲存,好比我本身的‘Teamwork’ app。
iOS 7中iCloud重要的簡化之一是fallback store的引入,它容許在iCloud accounts和iCloud Documents和Data之間無縫過渡。用戶可使用支持iCloud的app,即使他們沒有任何網絡鏈接,並在有可用網絡時把數據集成到iCloud中。
雖然這有點難以想象,基於iOS 7以前版本開發的 應用中,用於儲存用戶數據的本地存儲方案都應該被遺忘。
若是你僅打開iCloud,那你將使用一個不一樣的儲存,而且你將須要把用戶的本地數據合併到iCloud。在你嘗試把用戶數據集成到iCloud以前,你須要檢查如下幾點:
用戶註冊了iCloud嗎?
用戶想要在app中使用iCloud嗎?
用戶但願把本地數據合併到iCloud嗎?
若是以上的答案中有一個「no」,那麼這個app應該能在將來處理不一樣的答案。若是你的答案是「yes」,那麼你須要管理用戶本地數據遷移到iCloud的進程。當用戶的多個設備上存有本地數據時,事情就變得有趣了。若是是這樣,那你將須要考慮重複數據刪除策略了。
總結
若是說有一個iOS框架值得你投入時間,那就是Core Data。若是你對它感興趣,能夠考慮個人新書–Learning Core Data for iOS。這是本基於iOS 7的書,帶你領略整個Core Data的教程。可在此查看本書概要。