V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
dongsheng
V2EX  ›  iDev

大家怎么看Core Data?

  •  
  •   dongsheng · 2011-09-07 17:42:35 +08:00 · 11058 次点击
    这是一个创建于 4828 天前的主题,其中的信息可能已经有所发展或是发生改变。
    为项目中使用了Core Data而没用SQLite感到很后悔。

    我至今发现Core Data最大的优点就是NSFetchedResultsController了,这个对在表格里显示大量数据有好处。缺点发现一大堆:

    1. 代码冗长,一个带条件的查询些下来要十行,最后封装了一下好了一点,最大的问题是Core Data的API太另类了,加上objc,代码看起来真别扭,跟传统数据库查询差异太大。当然了Core Data不是数据库,它更像是带查询的对象持久化。
    2. 升级困难,官方文档用了Migration而不是upgrade,实际上对比较大幅度的改变,根本就是没法升级,只能把内容在新的存储介质中重建,这效率肯定上不去啊!这个应该是Core Data设计的问题,人家不是数据库。但这个后端存储不能灵活变化真是硬伤呐!另一个小问题是我做版本映射的时候,child entity没有默认把parent entity的属性做映射,然后数据都丢掉了,debug了半天才发现这个问题,最后得自己手动把parent entity的属性都加上。
    3. 用复杂SQL可以一句搞定的东西在Core Data里只能一步步用Core Data的API搞
    4. 线程问题,我有一个后台线程处理数据同步,但前端用户可能还会继续写入数据,最后我改成让core data在主线程上工作才解决这个问题,这不是个好办法,我还得再研究研究。

    但现在太晚了,要是再换成传统数据库又得烧进大量时间。请问大家怎么看Core Data?或者您在项目中用了那种数据持久化方案?
    20 条回复    1970-01-01 08:00:00 +08:00
    wang1986
        1
    wang1986  
       2011-09-07 18:17:08 +08:00
    牛刀?
    levey
        2
    levey  
       2011-09-07 18:19:07 +08:00
    CoreData比较麻烦,建议轻量级的sqlite封装。
    sharkli
        3
    sharkli  
       2011-09-07 19:55:50 +08:00
    我用了一段时间CoreData以后发现实在是麻烦。现在已经改成FMDB来操作db了。
    dongsheng
        4
    dongsheng  
    OP
       2011-09-07 20:01:27 +08:00
    @wang1986 这个什么意思?
    dongsheng
        5
    dongsheng  
    OP
       2011-09-07 20:09:08 +08:00
    @sharkli 看这篇文章时看到过这个库 http://inessential.com/2010/02/26/on_switching_away_from_core_data

    刚才想起core data还有个优点是在内存里操作数据,不是实时写入,这样对省电有好处。不知道FMDB能不能在内存中操作数据,改天研究下。
    gonefish
        6
    gonefish  
       2011-09-07 20:20:00 +08:00
    1.直接写的话,代码真是一堆。不过有一个查询编辑器,你可以设定条件,然后通过一个方法用占位符式把变量填进去。
    2.太复杂的升级,要手动写吧。
    dongsheng
        7
    dongsheng  
    OP
       2011-09-07 20:23:15 +08:00
    @gonefish
    2. 半手动,Xcode可以生成一个migration规则文件,然后写升级的代码,太麻烦了
    keakon
        8
    keakon  
       2011-09-07 20:23:37 +08:00
    @dongsheng 初学Core Data时曾经做过一个测试,批量插入、更新和删除数据时,它比SQLite慢2个数量级。而我经常需要批量更新几百条数据,差距基本上就是秒和毫秒级的,于是果断放弃了。
    gonefish
        9
    gonefish  
       2011-09-07 21:04:10 +08:00
    Core Data和SQLite根本就不是一个东西,比较速度没有意义。再说SQLite只是Core Data的一个持久介质。
    Mattsive
        10
    Mattsive  
       2011-09-07 21:50:11 +08:00
    当初看了一段 Core Data 文档后果断改用 FMDB 的飘过,整个项目就没在数据处理上花什么功夫。
    dongsheng
        11
    dongsheng  
    OP
       2011-09-07 22:37:29 +08:00
    难道没有对Core Data的正面评价?大家好像都是直接跳过Core Data这个方案了。。。
    dongsheng
        12
    dongsheng  
    OP
       2011-09-07 22:42:06 +08:00
    @keakon Core Data慢不奇怪,但真能差出数量级来?你是用NSFetchedResultsController还是直接读出数据集的?前者是lazy loading,性能不差的。
    keakon
        13
    keakon  
       2011-09-07 23:14:43 +08:00
    @dongsheng 直接操作啊,更新数据还要lazy干啥…印象中操作1000个花了4秒,而sqlite不到0.1秒。于是我立刻理解iReadG标记已读时为什么会阻塞半天主线程了…
    Kai
        14
    Kai  
    MOD
       2011-09-07 23:45:23 +08:00
    官方有说过这样一句:

    Core Data is not a relational database or a relational database management system (RDBMS).
    dongsheng
        15
    dongsheng  
    OP
       2011-09-07 23:59:13 +08:00 via iPhone
    @keakon 不在主线程操作有可能出现线程问题,可能也撞到我4里遇到的问题。
    dongsheng
        16
    dongsheng  
    OP
       2011-09-08 00:01:20 +08:00 via iPhone
    @Kai Hmmm 我记得我没说它是数据库吧?
    wtl
        17
    wtl  
       2011-09-08 10:13:12 +08:00
    @dongsheng https://github.com/ccgus/fmdb 试试这个 应该轻便许多

    另外 好奇楼主coredata底下的数据持久层用的是什么格式?
    wtl
        18
    wtl  
       2011-09-08 10:17:17 +08:00
    @dongsheng 4 .线程问题的话 把同步的任务及前端的写任务都抛到一个任务队列里 应该就解决了
    dongsheng
        19
    dongsheng  
    OP
       2011-09-08 10:37:54 +08:00
    @wtl

    我用的是SQLite做持久层,现在已经没法换了,现在有十几个实体models,再换数据库太费劲了。
    dongsheng
        20
    dongsheng  
    OP
       2011-09-08 10:40:58 +08:00
    @wtl
    > 4 .线程问题的话 把同步的任务及前端的写任务都抛到一个任务队列里 应该就解决了

    嗯,这个倒是,我今天实验下 :-)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1104 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 75ms · UTC 19:06 · PVG 03:06 · LAX 11:06 · JFK 14:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.