zoukankan      html  css  js  c++  java
  • Core Data 多线程操作实战篇

    最近在解决百度音乐iPhone客户端偶现数据库操作crash的问题,顺手整理了下CoreData的多线程原则,以及实际开发时应该如何遵守这些原则。

    Core Data多线程操作的基本原则

    1. 不允许跨线程访问MOC: 在某一个MOC上的CRUD操作只能在它的操作线程上进行
    2. 不允许跨线程访问MO:对MO的操作只能在它所属的MOC的操作线程上进行。需要注意的是,访问一个FRC的fetchedObjects数组也只能在FRC所属的MOC的操作线程上进行

    Core Data的新版本

    所谓的新版本,其实是从iOS 5.0就开始支持了。新版本的Core Data废弃了confinement context,替代它的是queue context。这两种context的区别在于,使用confinement context必须自己保证CRUD操作只在创建它的线程上执行,也就是说创建这个confinement context的线程就是它的操作线程。 而使用queue context则只需要用-performBlock:或者-performBlockAndWait:方法执行CRUD操作,这些操作都被dispatch到context持有的serial _dispatchQueue上执行。

    Magical Record的新版本(coming soon)

    根据Magical Record的说明,从3.0版本起,MagicalRecord中的-MR_contextForCurrentThread将被弃用。刚开始我没想清楚其中的原因,后来通过在github上提问,Magical Record的维护者之一tonyarnold给出的原因是:

    1. Core Data已经废弃了confinement context
    2. Core Data中新的queue context内部使用serial dispatch_queue来保证线程安全
    3. MR中的-MR_contextForCurrentThread方法是把一个queue context存储在一个thread的字典里。这样会导致调用这个方法的线程一定不是queue context的操作线程.

    我是这么理解的:

    1. 我们使用-MR_contextForCurrentThread这个方法通常的习惯是,拿到这个方法返回的context之后,直接在这个context上进行CRUD操作。这在旧版本使用confinement context的Core Data是没有问题的。因为这个confinement context的创建线程就是它的合法操作线程
    2. 对于queue context, 如果我们继续按照1中的方式使用这个context是有问题。原因就是tonyarnold给出的第三点。正确的做法应该是把CRUD操作都放在-performBlock:-performBlockAndWait:
    3. 我认为,如果我们能用正确的方式使用-MR_contextForCurrentThread方法返回的context, 那么是没有问题的

    App中应该如何遵守Core Data的多线程操作原则

    如果你App也使用了Magical Record, 那么建议你按照官方说明上的方式替换掉它打算废弃的API。比如用每次创建一个新的-MR_context的方式来替换掉-MR_contextForCurrentThread的使用。

    下面是我在修改百度音乐iPhone客户端的数据库操作时总结的几个方法:

    1. 每个入参有MO的方法

      1. 自己保证(不是由调用者保证)对MO的访问和修改在MO.managedObjectContext的操作线程上执行
      2. 此方法应该仅把DB操作放在MO.managedObjectContext的操作线程上。 这么要求是为了避免修改数据库操作之外的任务的线程安排
      3. 注意,不要把FRC.fetchedObjects作为参数传递。对这个数组做遍历、或者取大小等的操作必须要在FRC.managedObjectContext中进行,而仅由传入的FRC.fetchedObjects无法获取此信息
    2. MO的category中的方法

      1. -方法,没有必要用-performBlock:-performBlockAndWait:包起来。因为调用者应该有这样的意识:对MO的操作需要在它所属的MOC上进行。这点和CoreData的要求是一致的
      2. +方法需要自己保证不违反线程操作原则。 这点和MagicalRecord保持一致

    Core Data有关的Debug方式

    • -com.apple.CoreData.ConcurrencyDebug 3
    • -com.apple.CoreData.SQLDebug 3
    • -com.apple.CoreData.SyntaxColoredLogging YES
  • 相关阅读:
    mysql where中如何判断不为空
    python- with和上下文管理器
    python-面向对象-多态
    python
    python魔术方法- __init__,_new_,_call_,_str_,_repr_,_add_,_getitem_,_getattr_,_bases_,_dict_,_slots_
    jmeter 改变字体大小
    如何提高onenote同步速度?
    win10 中添加快捷方式到开始菜单
    解决win10电脑连上wifi但是无internet访问故障
    安装office2019版本后, vb无法引用Microsoft excel object library和Microsoft word object library 解决办法
  • 原文地址:https://www.cnblogs.com/mindyme/p/5089454.html
Copyright © 2011-2022 走看看