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

jopen 10年前發布 | 11K 次閱讀 IOS

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。


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的教程。可在此查看本書概要

原文出處: informit   譯文出處: cocoachina

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!