原文链接
http://iiiyu.com/2016/01/19/CoreData-VS-Realm/?utm_source=tuicool&utm_medium=referral
本文具有强烈的个人感情色彩,如有观看不适,请尽快关闭。本文仅作为个人学习记录使用,也欢迎在许可协议范围内转载或使用,请尊重版权并且保留原文链接,谢谢您的理解合作。如果您觉得本站对您能有帮助,您可以使用RSS方式订阅本站,这样您将能在第一时间获取本站信息。
碎碎念
OhMyStar 2 也进行了一段时日,我把持久化的方式从CoreData 换到了 Realm。有些感悟,顺手就记录一下吧。以下评论都是自己很主观的感受,无实际测试数据支持。
论 iOS 的持久化
iOS 持久化其实也没多少选择, 高端一点CoreData、Realm、FMDB、KV类(LevelDB等)。低端一些直接一个 NSArray 就写成 Plist 也能持久化下来。
在网络环境越来越快的当下和大部分应用数据都可能是网络应用,如果业务逻辑并不复杂,其实极端一点就只用写到 JSON 转 Object 就好了。而且一堆这样好用的封装,远有Mantle 近有YYModel。
所以需要持久化的时候,我觉的可以慎重的评估一下需求。想明白了,后面可以节省很多事情。
本文章主要对比 Realm 和 CoreData,其他的就不涉及了。
Realm
优点
入门门槛低
Realm文档就算一个字一个字扣着读完,一个下午就足够了。而且还有中文版本,不要太友好哦,有点不习惯诶。
文档覆盖了80%的使用情况,甚至有些太简陋的嫌疑。但不管怎么样,这种入门条件比起 CoreData 写了三个月都没搞清楚 Context 要好的多。
在库的工具链上,安装一个 Realm Browser 以后就不需要其他辅助了。还是简单。
几乎做到了上手即用的程度。五星好评。
PS:我用了一个通宵把 OhMyStar 2 的持久化从 CoreData 换到了 Realm ,优化调整了大概5天左右达到勉强可以用的情况 。在这之前并没有任何 Realm 的经验。
据说性能好一些
Realm官方介绍Fast一段中
Counts
Queries
Inserts
在写这里的时候我顺手Google了一下 发现一篇Core Data, FMDB, Realm 性能测试。我就多说几句
总觉得大家对 CoreData 误会蛮深,代码 Fork 看了一下, 总觉得不应该这样写来比性能的,但是一时半会也不知道怎么改。我只能说我在优化 CoreData 的时候根据 WWDC 上教的还是提升很高,另外一个事情是 CoreData 一般都用 Sqlite 做后端。所以如果你的查询是经过优化的,确认打出来的SQL语句科学以后,Sqlite(CoreData) 跟 Sqlite(FMDB)我觉得性能就算有差距,这差距没有能大到选择方案的决定性因素。如果使用 CoreData 遇到性能瓶颈,你应该仔细的研究 WWDC 和几篇很好的文章。确保你的 CoreData 使用方式是正确科学的。
没有需要架构Context那种烦人的东西
应该也算Realm简单的一个方面,Realm 只要保持自己线程里面,自己的 Realm Store 操作是正确的即可。如果是 CoreData,怎么架构一个科学的 Context Stack 就足够让我头疼一整,iOS 还好,界面是一个接着一个(VC跟VC之间的层级关系很清晰)。而 OhMyStar 2 这种 OS X 桌面应用场景VC之间很复杂,线程之间Context的关系让出现很多问题。
支持 NSPredicate
从 CoreData 转过来并没有太多的不适应
很简单的使用多个存储文件
举个例子,多用户登陆情况下。用户是单独的存储文件,和全部用户使用同一个存储文件。后者需要每条用户数据都要关联一次当前用户,所有查询用户数据的时候,你都必须加上当前用户的查询项。而使用每个用户单独一个数据文件的时候,整个存储结构会清爽很多。
技术支持
至少实在没法的时候还可以去微博上吐槽他们,他们其实也有极大的热情来解决你遇到的问题。CoreData 这种遇到问题就只能自己默默的吞下。
细粒化通知 (2016-02-23更新 0.98.x 版本以后可以获得精细化通知)
看最新的文档已经更新:
Notifications
看例子还可以进行filter。不要太友好哦。。。我很不习惯的。
有了这个通知在我思考的程序结构里,写入数据的所有线程都可以在后台了,而且更新UI的时候只用在需要的地方监听需要的类。这个进步让之前的缺点瞬间变成了优点,太棒了
缺点
关联关系弱的一逼
简单说来就是对象跟对象之间的一对多关系和多对多关系。并不能映射,需要在双方里面都写上属性,此外还需要在设置的时候两边同时设置。查询时候也是 NSPredicate 也仅仅只支持一些一层的查询,没法做出带SUBQUERY的复杂查询出来。
强制内省容错机制导致存储文件不断变大
Realm本身感觉有一个数据容错机制。但是这个机制在数据库文件有错误的情况自己修复的时候,会无限增大。具体我这里表现为,打开看只有3000条数据,但是文件大小已经有3GB。重现Bug也很容易,只要你在写数据库的时候,用Realm Browser查看一下,crash之后在打开就很容易出现。
官方文档里面有说到会造成这种情形的原因,我在尽我所能的避免问题以后。存储文件还是会有可能不那么夸张的变大一些。但是用Realm Browser查看数据是正常的。所以我觉得官方应该提供一个函数,可以删除掉那些容易的东西。保持存储文件的干净。
2016-02-23更新: 楼下Realm的同学留言说了其中一种解决方法。可以使用Realm.writeCopyToPath()
来手动释放旧版本使用的空间。当然这些空间在没有 Realm 实例引用的情况下是会被自动重用的。我理解的意思是在开启或者关闭App的时刻,把Realm实际的数据库写到tmp里再把当前的realm关闭然后拷贝回来。会变大的原因肯定还是线程的问题。 我的被我写的有些乱,期望我能把他优化好吧。
增加包体积
据官方说会增加1MB左右的包大小,如果你是一个小体积应用,或者是一个几千万用户的主流应用。对包大小敏感的话慎用。
2016-02-23更新:实际测试我在Mac上的adhoc包有3MB多。
核心代码目前闭源
对于在我们这样一个作恶满天飞的天朝长大的孩子来说,有些孩子对闭源这个事情还是挺在意的。不过官方说将来会开源,我还是倾向于相信 Realm 他们的人品。
CoreData
CoreData 相关资料相对多一些我就简单说
优点
官方支持 && 亲儿子
系统自带,Apple支持
带图形化的Model编辑
对于视觉化动物来说比较友好,也可以清楚的知道自己设计的 Model 之间的关系
强大的关联关系
以前不觉得,用了 Realm 才发现 CoreData 的关联关系如此好用,一对多,多对多。想怎么查询就怎么查询,可以写出很复杂的查询逻辑来。
强大的查询
虽然可能在设置NSFetchRequest的时候感觉很多东西要弄,但是复杂也带来了强大的功能,NSFetchRequest 可以设置很多,比如限制查询数量, 限制只返回某些属性值等等。就不展开说了。
精细化的通知
可以知道具体插入了什么、更新了什么、删除了什么。这样在刷UI,比如一个tableview的时候,你就可以控制的很准确。
缺点
入门门槛高
CoreData 是一个博大精深的技术,不要妄想几天之内可以用的很溜。CoreData 是一个博大精深的技术,不要妄想几天之内可以用的很溜。CoreData 是一个博大精深的技术,不要妄想几天之内可以用的很溜。
如果没有足够的时间和精力去接入 CoreData。 那选型的时候应当慎重考虑。
需要一些工具才感觉好使
不管是老手还是新手,使用一些第三方的封装库和工具都会大大的提高使用 CoreData 的幸福指数。
mogenerator 是必须必须要的。
MagicalRecord 无愧 CoreData 第一库,据小道消息 主要贡献者 Saul Mora 可能去了微信了。
Context
其实还是 CoreData 门槛高的问题,对我来说。Context之间的关系和线程之间的处理让我感到很头痛,特别是 OS X 是一大堆VC铺到屏幕上,我水平又菜,出的问题很多。
多个持久化文件很麻烦
不是说不可以,但是真的好麻烦。
有个第三方库有解决CoreData这个问题 CoreStore 但是我用着不是很顺手最后弃用.
总结
其实吧用啥持久化都行,具体还是需要看你的需求和方案上来说哪一个方案更加适合。
如果简单说来,就是 Realm 更加适合一些业务逻辑不怎么复杂的场景,团队配置要求不高,有经验的人稍微看一下午就能上手。
CoreData 更加适合业务逻辑复杂的情况,团队配置要求比较高,有经验的老手也需要几周甚至更长的时间才能科学的使用CoreData。