天天看點

iOS 開發中使用 Core Data 應避免的十個錯誤

iOS 開發中使用 Core Data 應避免的十個錯誤

core data是蘋果針對mac和ios平台開發的一個架構主要用來儲存資料。對很多開發者來說core data比較容易入手但很難精通如果沒有正确的學習方法你将很難真正了解它更不用說精通了。很多開發者常常在這方面犯一些錯誤而這篇文章列出了 開發者在ios開發過程中使用core data常見的一些錯誤并對如何避免這些錯誤進行了分析。

1.不了解關鍵術語

對于ios開發者來說會使用core data是一項必備技能。 沒有它很多app都不會存在。當在網際網路上四處搜尋core data學習教程你很容易被各種各樣的術語吓倒。事實上大部分學習教程都首先假定你已經知道了這些術語而如果你不了解這些術語那将會陷入困惑中。所 以首先要知道關鍵的術語。這裡有一個備忘單可以用在學習core data的過程中這份備忘單展示了關鍵的詞組

iOS 開發中使用 Core Data 應避免的十個錯誤

在以後的學習過程中你會遇到更多的術語但這些是初學者需要了解的最基本的部分。

2.完全忽視core data

當一項技術以難學“聞名”時你可能會忽略它特别是當你時間不夠急着把app做出來的時候。

core data儲存app資料的一個常見替代選擇是使用xml屬性清單雖然屬性清單可以讓你今天的工作變得輕松但它們也會随後回過頭來咬你一口。無論何時你 編輯屬性清單發生的變化都是原子性的。這意味着即便是很小的更改要求整個檔案都會被加載到記憶體中然後在儲存的時候整個檔案都會被寫回到硬碟。

随着資料量的增長app也會變得越來越慢。但是如果你基于sqlite資料庫使用core data時這些性能問題就不會困擾你 。這樣可以保持低記憶體占用以保證app快速響應并防止app因記憶體壓力過大而崩潰。本質上說core data之是以比屬性類表更有擴充性的原因是它支援使用資料庫進行持久性儲存。可擴充性并不是core data的唯一優勢使用關系把資料組織進實體結構才是其強大之處。比如考慮使用以下實體來代表一個任務

iOS 開發中使用 Core Data 應避免的十個錯誤

該任務實體包含一個名稱和subtask_name屬性。當從任務實體中建立管理對象時它将會有一個名稱和subtask_name屬性。

不依賴關系這個資料模型僅支援一個subtask現在考慮以下實體

iOS 開發中使用 Core Data 應避免的十個錯誤

帶有雙箭頭的線表明task entity可以對應多個subtask entity關系這意味着一個任務可以有多個子任務更不必說涉及到的父任務也能通過逆關系被包含進來。這個靈活性不僅友善更節省了資料庫的空間因 為父任務名稱僅僅隻需儲存一次。如果你想要更進一步讓任務有子任務的子任務下一步該怎麼辦思考下重新建構以下任務實體

iOS 開發中使用 Core Data 應避免的十個錯誤

模型現在支援無線深度的子任務因為任務實體關聯的是其本身core data的可擴充性和靈活性還隻是其優勢中很少的一部分。core data并不僅僅利用關系資料庫的優勢而且你不必寫任何sql語句來使用它。core data替你承擔了責任并且為你自動優化了生成的sql語句。

我還沒有深入研究core data的其他價值方面比如模型版本控制、遷移、驗證以及變更管理和icloud同步等等。如果有任何值得你投入時間的ios架構那就是core data。

不使用模型版本控制和遷移

如果你已經編輯了一個管理對象模型你可能已經犯了以下錯誤

“此前用來打開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, 34…

删除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的教程。可在此檢視本書概要。

原文出處 informit 譯文出處 cocoachina