持久化方案
在 iOS 開發(fā)中,數(shù)據(jù)持久化存儲是一個很常見的需求颈渊。所謂持久化存儲淋昭,就是將數(shù)據(jù)存到硬盤俐填,使得應用重啟時還能從硬盤重新讀取數(shù)據(jù)悟泵。來看看一些常見的持久化方案警没。
NSUserDefault
NSUserDefault 用來存儲用戶偏好設置和應用配置信息磅摹,適合小規(guī)模的數(shù)據(jù)花墩。常見的比如應用啟動的時候是否需要展示引導頁篱昔,就可以在這里設置一個是否已顯示過的標志屁置。它的背后實際上是一個特殊的 .plist
文件蕾盯。
Keychain
Keychain 用來存儲一些敏感的數(shù)據(jù)竹揍,比如密碼材失,token 等痕鳍。由于相關的 API 比較底層,我們可以使用對其做了封裝的更友好的第三方庫龙巨,比如 FXKeychain笼呆。
文件
-
Plist:
.plist
文件用來存儲小規(guī)模的結構化的數(shù)據(jù),用到的時候可以很方便的讀取旨别。常見的比如“省-城市”數(shù)據(jù)诗赌。但存儲對象類型只能是這些:NSData
,NSString
昼榛,NSNumber
境肾,NSDate
剔难,NSArray
,NSDictionary
奥喻。 -
NSKeyedArchiver:由于
Plist
對存儲對象類型的限制偶宫,如果想存更大量的,結構更復雜的對象环鲤,就可以用歸檔纯趋。只需要自定義的數(shù)據(jù)類型遵守NSCoding
協(xié)議。
數(shù)據(jù)庫
上面提到的幾種方案都是很輕量級的冷离,一旦數(shù)據(jù)量更大吵冒,數(shù)據(jù)結構及關聯(lián)關系更復雜,需要更頻繁和方便的增刪改查西剥,我們就需要用上數(shù)據(jù)庫來滿足這些需求了痹栖。我們目前有這三種選擇:
數(shù)據(jù)庫方案
這里不展開講每個方案的細節(jié),畢竟數(shù)據(jù)庫是計算機科學的一大知識體系瞭空,需要很深厚的功力才能講得明白揪阿。我只講講方案選擇的思路。
SQLite vs. Core Data/Realm
SQLite 是一個輕量級的跨平臺數(shù)據(jù)庫咆畏,適合存儲查詢需求較多南捂,查詢條件更復雜的數(shù)據(jù)。我曾經(jīng)做過的一個項目中不同的移動平臺使用了由服務端導出的同一個數(shù)據(jù)庫旧找,因為數(shù)據(jù)較多條件較復雜還專門請教了別的組的數(shù)據(jù)庫專家來幫我們優(yōu)化 sql 語句溺健。
雖然 SQLite API 是基于 C/C++ 的,對習慣了面向對象編程的我們不夠友好钮蛛,但是不用擔心鞭缭,有很多第三方庫對它做了很好的封裝。比如 FMDB愿卒,讓數(shù)據(jù)庫操作更簡單易懂缚去。也因為它更底層,所以在數(shù)據(jù)查詢時可以更加靈活琼开。
但是 SQLite 有個讓人無法忽視的缺點易结,就是需要我們手動搭建模型層,完成數(shù)據(jù)庫表到對象模型的映射柜候。所以搞动,如果項目的數(shù)據(jù)規(guī)模較小,查詢復雜度較小渣刷,又注重對象之間的關聯(lián)關系鹦肿,可以優(yōu)先選擇 Core Data/Realm 來更方便地搭建模型層。
Core Data vs. Realm
Core Data 在嚴格意義上來說辅柴,并不是數(shù)據(jù)庫箩溃,而是由 Apple 提供的一套完整的數(shù)據(jù)管理方案瞭吃,它的底層是通過 SQLite,XML 或二進制文件存儲數(shù)據(jù)的涣旨。在數(shù)據(jù)存儲之上歪架,又提供了數(shù)據(jù)模型的解決方案∨福可以說它搭起了下層數(shù)據(jù)和上層對象之間的橋梁和蚪,將關系型數(shù)據(jù)轉成對象,并通過對象圖組織起來烹棉,進行自動管理攒霹。同時使得開發(fā)者可以面向對象編程〗矗可以參考我之前寫的一篇文章催束。
Realm 是近幾年興起的并保持良好發(fā)展勢頭的全新的數(shù)據(jù)庫方案。它不像 Core Data 那樣采用 SQLite 作為內部核心辅髓,而是從頭構建了自己的數(shù)據(jù)庫引擎泣崩,獲得了更好的性能。它最核心的理念是對象驅動洛口,從而避免 ORM 架構以及其帶來的抽象方式。它還是跨平臺的凯沪,支持 iOS/macOS第焰,Android。
一個是官方支持妨马,經(jīng)過漫長時間和無數(shù)應用的檢驗的 Core Data挺举,一個是由第三方團隊開發(fā)的,年輕但長勢喜人的 Realm烘跺,我們該如何選擇呢湘纵。
雖然 Realm 并沒有完全解決 Core Data 那些令人頭痛的問題,比如多線程問題滤淳,但它也確實做出了一些改進提升了開發(fā)體驗梧喷。所以我個人的觀點是,優(yōu)先選擇 Realm脖咐。具體原因最主要有以下兩點:
- 更容易上手铺敌。我猜每一個開發(fā)者應該都曾吐槽過 Core Data 那陡峭的學習曲線吧。而 Realm 讓開發(fā)者很容易就能創(chuàng)建一個模型屁擅,只要繼承
RLMObject
就好了偿凭!除了簡潔的 API,Realm 還提供了清爽的文檔派歌,Xcode Plugin弯囊,Realm Browser痰哨,讓開發(fā)體驗更上一層樓。 - 更年輕匾嘱,更有活力作谭。Core Data 老了,它已經(jīng)有很長一段時間沒有得到實質性的改進奄毡≌矍罚可能是 Apple 的工程師都忙著研究新技術等下一次發(fā)布會時震驚世界吧。而 Realm 有它的雄心壯志吼过,它采用了更先進的技術锐秦,正在一點點變得更強大。除了 Realm 這個產品盗忱,Realm 團隊還致力于創(chuàng)建更好的 iOS 開發(fā)社區(qū)酱床,源源不斷地發(fā)布了很多高質量的文章,是我最近非常喜歡做深入閱讀的地方趟佃。
有人可能會提到性能問題扇谣,實際上移動端對數(shù)據(jù)庫性能的要求遠沒有服務器端來的苛刻。一般規(guī)模的應用更注重的是代碼的可維護性闲昭,最后才是性能調優(yōu)罐寨。所以不同的數(shù)據(jù)庫方案在性能方面雖然有所差異但對實際項目的影響幾乎可以忽略。
總結
如果應用數(shù)據(jù)復雜度高序矩,有頻繁的讀寫需求鸯绿,復雜的查詢條件,可以選擇 SQLite簸淀。但一般情況下瓶蝴,選擇更容易上手,API 更簡潔租幕,對開發(fā)者更友好的 Realm 吧舷手。