上周有幸參加了Realm
全球行北京站的大會分享,大會的氛圍很輕松,有很多Realm
周邊(包括一件紀(jì)念T恤??)可以拿,還有很多免費(fèi)的小食和啤酒愿待,與其說是大會,不如說是一個party??靴患∪越模總的來說感覺非常的興奮,尤其是Realm
的新產(chǎn)品鸳君,Realm Mobile Platform
农渊。唯一比較遺憾的是中途家中有事離場,沒能完整的參加整個大會或颊。
Realm Mobile DataBase
第一場演講是由Realm研發(fā)團(tuán)隊(duì)中唯一的國人陳牧龍砸紊,陳老師為我們帶來的,主要的內(nèi)容是 Realm Mobile DataBase的使用囱挑,以及常見問題的原因和解決方法醉顽。說全稱大家可能不太習(xí)慣,不過Realm Mobile DataBase就是當(dāng)初那個讓你入坑realm的開源免費(fèi)的產(chǎn)品平挑。如果你使用過realm的話你一定明白為什么官方敢于說出自己是SQLite和CoreData的代替者游添。如果你沒用用過,那么讓我們來簡單體驗(yàn)一下realm是多么的方便通熄。
創(chuàng)建對象
class Dog: Object {
dynamic var name = ""
dynamic var age = 0
}
let dog = Dog()
dog.name = "Rex"
dog.age = 1
Realm致力于盡可能讓對象的操作無限接近與普通的對象否淤,比如上面的代碼就非常簡單清晰的定義創(chuàng)建了一個Dog
對象,有兩個屬性 name 和 age棠隐。沒有一句sql語句,也不需要我們像CoreData
那樣去.xcdatamodeld
文件中創(chuàng)建實(shí)體再生成模型文件檐嚣。
寫入
let realm = try! Realm()
try! realm.write {
realm.add(dog)
}
通過這個閉包助泽,我們就成功的將剛剛創(chuàng)建的dog對象添加到了Realm中啰扛。當(dāng)然這個閉包中其實(shí)做了很多事情比如開啟結(jié)束事務(wù)(transaction),創(chuàng)建新版本的鏡像realm文件等嗡贺,但是我們完全不需要在意隐解,只需要一個簡單的閉包,就可以將我們的對象寫入realm文件诫睬,進(jìn)行持久化操作煞茫。
查詢
let pups = realm.objects(Dog.self).filter("age < 2")
托Swift
的福,即使是原本要寫三四行的查詢操作摄凡,我們也可以很清爽的使用一行代碼寫完??续徽。上面的代碼中查詢出了當(dāng)前realm文件中所有的Dog
對象,并且過濾掉出了age < 2
的部分亲澡。
為什么Realm更快
個人理解Realm速度更快钦扭,主要體現(xiàn)在兩個方面,一個是線程操作時的加鎖機(jī)制MVCC床绪,另一個就是懶加載客情。
MVCC
先聲明一下MVCC
和MVC
的關(guān)系就跟JavaScript
和Java
一樣??
MVCC
全稱為 Multi-Version Concurrency Control
多版本并發(fā)控制,屬于數(shù)據(jù)庫的一種機(jī)制癞己,在解釋MVCC之前我們先來了解以前普通的SQLite在遇到多線程讀寫的時候是怎么處理的吧膀斋。
傳統(tǒng)的SQLite
在面對寫入操作的時候?yàn)榱吮苊庖驗(yàn)槎嗑€程操作到時讀取到只寫入了一部分的信息,采取了有寫入操作的時候就會對數(shù)據(jù)庫文件加鎖痹雅,這樣可以很好的避免因?yàn)槎嗑€程導(dǎo)致的信息讀取錯誤問題仰担,但是也會帶來一個很明顯的問題,那就是會阻塞當(dāng)前的讀取操作所在線程练慕,如果當(dāng)前讀取操作是在UI線程中進(jìn)行的惰匙,那么就會表現(xiàn)為APP卡頓。
而Realm則是會在有數(shù)據(jù)寫入的時候創(chuàng)建一個新版本的文件V2铃将,并且在V2中進(jìn)行寫入项鬼,此時如果有讀取操作進(jìn)入的話,realm會將讀取操作指向原來的版本V1劲阎。當(dāng)wirte操作結(jié)束的時候绘盟,realm會銷毀掉原來的V1,并用新版本的V2來代替原來的V1悯仙。這樣讀取操作就永遠(yuǎn)不會被寫入操作所阻塞龄毡。同時還可以避免讀取到錯誤的信息。
當(dāng)然锡垄,這個特性的背后其實(shí)還有一個大坑沦零,那就是V1版本的銷毀實(shí)際依賴的是事件循環(huán),也就是說如果我們在運(yùn)行循環(huán)沒有打開的子線程進(jìn)行寫入操作的話货岭,V1版本將不會被銷毀路操。也就是說寫入操作結(jié)束后疾渴,沒有任何用處的V1也會一直保存在你的磁盤中,結(jié)果就是APP所占的空間會越來越大屯仗。解決方案就是把realm對象放到autoreleasepool
里面搞坝。
除了MVCC,Realm還做了十分接地氣的一件事情魁袜,那就是把所有的操作就盡可能的放在后臺線程去執(zhí)行桩撮,而不是占用你的UI線程。這是很符合移動開發(fā)習(xí)慣的一點(diǎn)??
懶加載
個人認(rèn)為Realm
另一個可以戰(zhàn)勝SQLite
的地方就是Realm
的讀取信息為懶加載峰弹。比如當(dāng)你查詢Dog
對象結(jié)束的時候店量,你的內(nèi)存中是不會存在Dog
的name
和age
的信息的。只有當(dāng)你真正調(diào)用了Dog
的name
字段垮卓,Realm
才會用磁盤中讀取name
信息垫桂,并且加載到內(nèi)存中,這一個特性極大的提高了Realm的查詢速度粟按。
此外Realm還有很多其他讓人興奮的特性诬滩,比如細(xì)粒化通知灭将,數(shù)據(jù)庫文件加密等等疼鸟,大家可以再官網(wǎng)看到更詳細(xì)的說明。
Realm Mobile Platform
這是Realm
的一個新的產(chǎn)品庙曙,負(fù)責(zé)介紹它的是一個韓國歐巴空镜,我并沒有使用過,但是聽過它的介紹以及演示之后捌朴,我也是決定下一個項(xiàng)目一定要嘗試使用它吴攒。Realm Mobile Platform
簡單來講就是將你原來的模型與本地realm
文件的映射關(guān)系擴(kuò)展為模型對象與服務(wù)端server
的映射關(guān)系。也就是說砂蔽,我們甚至可以拋棄AFNetworking
之類的網(wǎng)絡(luò)請求框架洼怔,只是執(zhí)行類似于查詢的操作,就可以從server
端不同到數(shù)據(jù)左驾,而且一旦server
端的數(shù)據(jù)發(fā)生了變化镣隶,你可以通過通知得到這些改變,本地的數(shù)據(jù)有了改動一樣也可以自動提交到server端诡右。不得不說這是非常cool
的一件事情安岂。當(dāng)然,這種類似查詢的網(wǎng)絡(luò)請求也是https的帆吻,而且Realm Mobile Platform
是離線優(yōu)先的域那,所以你不用擔(dān)心因?yàn)闆]有網(wǎng)絡(luò)導(dǎo)致的種種問題。原本的IM模塊猜煮,數(shù)據(jù)即時推送琉雳,用戶信息統(tǒng)計(jì)等等模塊可能需要接入很多三方样眠,現(xiàn)在,你只需要一個Realm Mobile Platform
就可以輕松的完成這些內(nèi)容翠肘,并且只需要很少的代碼。??
順便提一下韓國歐巴還是挺可愛的辫秧,講話也很風(fēng)趣束倍,自己分享完還在碎碎念因?yàn)楫?dāng)前的國際形勢,很擔(dān)心自己能不能入境之類的 :D
總之很開心能夠參加這次大會盟戏,希望能參加更多類似的大會吧绪妹。