上周有幸参加了Realm
全球行北京站的大会分享,大会的氛围很轻松,有很多Realm
周边(包括一件纪念T恤😊)可以拿,还有很多免费的小食和啤酒,与其说是大会,不如说是一个party🍺。总的来说感觉非常的兴奋,尤其是Realm
的新产品,Realm Mobile Platform
。唯一比较遗憾的是中途家中有事离场,没能完整的参加整个大会。
Realm Mobile DataBase
第一场演讲是由Realm研发团队中唯一的国人陈牧龙,陈老师为我们带来的,主要的内容是 Realm Mobile DataBase的使用,以及常见问题的原因和解决方法。说全称大家可能不太习惯,不过Realm Mobile DataBase就是当初那个让你入坑realm的开源免费的产品。如果你使用过realm的话你一定明白为什么官方敢于说出自己是SQLite和CoreData的代替者。如果你没用用过,那么让我们来简单体验一下realm是多么的方便。
创建对象
class Dog: Object {
dynamic var name = ""
dynamic var age = 0
}
let dog = Dog()
dog.name = "Rex"
dog.age = 1
Realm致力于尽可能让对象的操作无限接近与普通的对象,比如上面的代码就非常简单清晰的定义创建了一个Dog
对象,有两个属性 name 和 age。没有一句sql语句,也不需要我们像CoreData
那样去.xcdatamodeld
文件中创建实体再生成模型文件。
写入
let realm = try! Realm()
try! realm.write {
realm.add(dog)
}
通过这个闭包,我们就成功的将刚刚创建的dog对象添加到了Realm中。当然这个闭包中其实做了很多事情比如开启结束事务(transaction),创建新版本的镜像realm文件等,但是我们完全不需要在意,只需要一个简单的闭包,就可以将我们的对象写入realm文件,进行持久化操作。
查询
let pups = realm.objects(Dog.self).filter("age < 2")
托Swift
的福,即使是原本要写三四行的查询操作,我们也可以很清爽的使用一行代码写完🎉。上面的代码中查询出了当前realm文件中所有的Dog
对象,并且过滤掉出了age < 2
的部分。
为什么Realm更快
个人理解Realm速度更快,主要体现在两个方面,一个是线程操作时的加锁机制MVCC,另一个就是懒加载。
MVCC
先声明一下MVCC
和MVC
的关系就跟JavaScript
和Java
一样🙄
MVCC
全称为 Multi-Version Concurrency Control
多版本并发控制,属于数据库的一种机制,在解释MVCC之前我们先来了解以前普通的SQLite在遇到多线程读写的时候是怎么处理的吧。
传统的SQLite
在面对写入操作的时候为了避免因为多线程操作到时读取到只写入了一部分的信息,采取了有写入操作的时候就会对数据库文件加锁,这样可以很好的避免因为多线程导致的信息读取错误问题,但是也会带来一个很明显的问题,那就是会阻塞当前的读取操作所在线程,如果当前读取操作是在UI线程中进行的,那么就会表现为APP卡顿。
而Realm则是会在有数据写入的时候创建一个新版本的文件V2,并且在V2中进行写入,此时如果有读取操作进入的话,realm会将读取操作指向原来的版本V1。当wirte操作结束的时候,realm会销毁掉原来的V1,并用新版本的V2来代替原来的V1。这样读取操作就永远不会被写入操作所阻塞。同时还可以避免读取到错误的信息。
当然,这个特性的背后其实还有一个大坑,那就是V1版本的销毁实际依赖的是事件循环,也就是说如果我们在运行循环没有打开的子线程进行写入操作的话,V1版本将不会被销毁。也就是说写入操作结束后,没有任何用处的V1也会一直保存在你的磁盘中,结果就是APP所占的空间会越来越大。解决方案就是把realm对象放到autoreleasepool
里面。
除了MVCC,Realm还做了十分接地气的一件事情,那就是把所有的操作就尽可能的放在后台线程去执行,而不是占用你的UI线程。这是很符合移动开发习惯的一点👍
懒加载
个人认为Realm
另一个可以战胜SQLite
的地方就是Realm
的读取信息为懒加载。比如当你查询Dog
对象结束的时候,你的内存中是不会存在Dog
的name
和age
的信息的。只有当你真正调用了Dog
的name
字段,Realm
才会用磁盘中读取name
信息,并且加载到内存中,这一个特性极大的提高了Realm的查询速度。
此外Realm还有很多其他让人兴奋的特性,比如细粒化通知,数据库文件加密等等,大家可以再官网看到更详细的说明。
Realm Mobile Platform
这是Realm
的一个新的产品,负责介绍它的是一个韩国欧巴,我并没有使用过,但是听过它的介绍以及演示之后,我也是决定下一个项目一定要尝试使用它。Realm Mobile Platform
简单来讲就是将你原来的模型与本地realm
文件的映射关系扩展为模型对象与服务端server
的映射关系。也就是说,我们甚至可以抛弃AFNetworking
之类的网络请求框架,只是执行类似于查询的操作,就可以从server
端不同到数据,而且一旦server
端的数据发生了变化,你可以通过通知得到这些改变,本地的数据有了改动一样也可以自动提交到server端。不得不说这是非常cool
的一件事情。当然,这种类似查询的网络请求也是https的,而且Realm Mobile Platform
是离线优先的,所以你不用担心因为没有网络导致的种种问题。原本的IM模块,数据即时推送,用户信息统计等等模块可能需要接入很多三方,现在,你只需要一个Realm Mobile Platform
就可以轻松的完成这些内容,并且只需要很少的代码。🤠
顺便提一下韩国欧巴还是挺可爱的,讲话也很风趣,自己分享完还在碎碎念因为当前的国际形势,很担心自己能不能入境之类的 :D
总之很开心能够参加这次大会,希望能参加更多类似的大会吧。