Core Data 多线程设计

原文:Core Data系列四——多线程设计

1. 线程访问限制

  • NSManagedObjectContext 不允许跨线程操作
  • NSManagedObject 不允许跨线程访问

两处所说的线程指的NSManagedObjectContext类私有的_dispatchQueue, 我把它叫做MOC的操作线程.
MOC还有另外一个私有的_queueOwner, 指的是创建这个MOC的线程,我把它叫做MOC的所属线程这两者不是一回事

本节参见:
Core Data Programming Guide: Concurrency
NSManagedObjectContext | Apple Developer Documentation

2. NSManagedObjectContext与多线程相关的说明

MOC有两种类型: 基于线程限制的和基于queue的。

  1. 基于线程限制的MOC,需要保证在MOC的所有操作需要在它的创建线程上。也就是说, 它的操作线程所属线程为同一个线程。这种类型的MOC是通过-init方法初始化的,且要求它的parent store是PSC。
    使用这种基于线程限制的MOC时,需要编程者自己保证仅在它的创建线程上操作它

  2. 基于queue的MOC,为了保证它的所有操作都在其操作线程上(且其操作线程私有),只需要把操作包装在performBlock:或者performBlockAndWait:中。而这两个方法本身是可以在任意线程中调用的。这种类型的MOC,其操作线程和所属线程一般不是同一个线程(NSMainQueueConcurrencyType类型的是例外)。
    以上两种类型的MOC, 其所属线程均为调用它的init方法的线程。

3. 数据同步

当操作线程为A的MOC里的数据有变化时,另一个操作线程为B的MOC如何同步这种变化呢? 两种方案:

  1. 通过监听NSManagedObjectContextDidSaveNotification通知,主动merge.
  2. 通过parent/child nested context. 当child context做save操作后,这种变化会自动同步到parent context中。

MagicalRecord是针对Core Data的二次封装,很好的处理了多线程相关的操作。另外一篇文章中简单分析了MagicalRecord的设计,感兴趣的可以阅读一下。

本节参见:
https://forums.pragprog.com/forums/252/topics/12271
http://oleb.net/blog/2014/06/core-data-concurrency-debugging/#fnref:3

4. 常见的多线程设计方案

根据Core Data大神Florin Kugler的介绍,app中常见的多线程设计的方案有一下三种:
方案1:
在这里插入图片描述

方案2:
在这里插入图片描述

方案3:
在这里插入图片描述

从性能上看,这三种方案中第一种方案对主线程的影响最大。因为虽然耗时的数据操作是放在Bg MOC中操作的,但最终持久化到DB中以及从DB中获取数据均需要通过main MOC。第二种方案的设计的性能介于第二种和第三种之间,但各个context之间的数据同步是通过parent context关系自动同步的,比较优雅。第三种方案的性能最优,但context之间是通过通知来进行的,相对比较复杂。 其中第二种方案的性能差于第三种方案,说明自动save的成本还是比主动merge的成本要高的。

ObjC 中国 - Core Data 试读

5. 关于Core Data多线程的debug

iOS 8.0以上,在 Arguments中添加:-com.apple.CoreData.ConcurrencyDebug 1,系统便会自动加载CoreData debug版本的库。当违反了多线程操作原则时便会强制crash。
说明:本文为原创内容,转载请注明出处

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值