正确使用Core Data多线程的3种方式
在#Pragma Conference 2015会议上,Marcus Zarra,撰写过关于Core Data和Core Animation的书,叙述了三种在多线程环境下使用Core Data的方法并且设法解决在2015年应如何使用Core Data的问题。实际上,Zarras说道,当用一个拥有十一年历史的技术比如Core Data工作时,你所面临的问题之一是有大量的信息是可用的,不过查明哪一份信息依旧精确以及哪一份不精确并不是一件简单的事。
根据Zarras所言,当我们知道我们仍旧有空余的CPU时我们应该使用多线程,那样我们可以预先处理用户接下来要使用的数据。多线程另外一个很重要的用例是通过允许用户不必等待一个冗长的操作来完成,来改进一个app的灵敏程度,比如网络操作。多线程几乎从来不是解决性能问题的办法并且它是一种基础设计决策,而不是一个事后的想法。
最初的方法
最初的方法是在iOS 6推出之前唯一可用的方法。这个方法现在依然可以使用,尽管Zarra建议除了在某些极端情况以外不要使用它。它基于四个主要的原则:
- 一个NSPersistentStoreCoordinator(PSC)处理所有磁盘之间的相互影响。
- NSManagedObjectContexts (MOCs)与PSC对话并且不知道对方的任何情况。
- 其中一个MOCs负责UI的更新并且在单一可信来源上起作用。
- 一个MOC开始意识到另一个MOC的变化的唯一方法是通过merging 合并处理一个NSNotification。

这个设计有一些不足之处,比如需要写很多公式化的代码,线程规则不明确会导致不定时发生崩溃以及意外线程阻塞。随着推出了iOS 8,这些问题改善了一些。并且多亏了一个debug flag调试标志,Yosemite才能在它违反Core Data并发模型的时候让应用程序崩溃。
艰难的方法
Zarras称之为艰难的方法的是一个依赖于用于多进程访问SQLite的方法。这就意味着我们可以拥有多个PSC,让每个MOC都可以拥有自己的PSC。这会对摆脱任何锁定问题起到很好的作用并且启用几乎所有异步访问——除非你没有写相同的表以及同时把两个PSC排成一行。
即使有了这个设计,只用一个MOC来把数据反馈到UI是可取的。这个方法会让用PSC来同步数据变得艰难,因为它们不知道对方的任何情况。此外,线程和可维护性也会被损害。这个方法有趣的一面在于,这就是iCloud如何运作的真实写照。
最好的方法
根据Zarra所言,最好的办法并不是速度最快的,但它是到目前为止最简单和最可持续的方法。它依靠苹果和iOS 6一起推出的new APIs,new APIs允许定义子MOC并且详细描述一个MOC的并发类型。Zarra呈现的这个设计是基于NSManagedDocument如何运作和使用的:
- 一个单独的持久性数据协调器。
- 唯一能实际访问PSC的一个私有的MOC。
- 一个主要的MOC联合UI,它是私有的MOC的子设备。
- 多个子MOC具体到辅助线程。

这个设计的好处是子MOC所有的变化会自动传送到其主MOC上,因此消除了合并的需求。
这个设计的主要缺陷是它速度缓慢,尽管只是慢了百分之几,Zarra说道。它有一个很棘手的问题就是如果进行太多的异步操作,有可能会在UI上起连锁反应,因为其相关的MOC会受到序列的多重变化,这可能与另一个并不相干。
这个设计一个很重要的细节就是最好不要重复使用很便宜就能创造的子MOC。另一方面,能用很久的子MOC应该与主MOC手动保持同步,因为变化仅仅是从子MOC到主MOC而反之则不行。
Zarra的最后评论是使用NSManagedDocument会锁定UI,所以你最好做好准备。
查看英文原文:Three Ways to Get Core Data Multithreading Right
正确使用Core Data多线程的3种方式的更多相关文章
- c#使用多线程的几种方式示例详解
本文转载自:http://www.jb51.net/article/46234.htm 本文章主要介绍了c#使用多线程的几种方式,通过示例学习c#的多线程使用方式,大家参考使用吧 (1)不需要传递参数 ...
- Java多线程系列--“基础篇”02之 常用的实现多线程的两种方式
概要 本章,我们学习“常用的实现多线程的2种方式”:Thread 和 Runnable.之所以说是常用的,是因为通过还可以通过java.util.concurrent包中的线程池来实现多线程.关于线程 ...
- java多线程系类:基础篇:02常用的实现多线程的两种方式
本章,我们学习"常用的实现多线程的2种方式":Thread 和 Runnable.之所以说是常用的,是因为通过还可以通过java.util.concurrent包中的线程池来实现多 ...
- Java实现多线程的两种方式
实现多线程的两种方式: 方式1: 继承Thread类 A: 自定义MyThread类继承Thread类 B: 在MyThread类中重写run() C: 创建MyThread类的对象 D: 启动线程对 ...
- c# 多线程的几种方式
1.什么是线程? 进程作为操作系统执行程序的基本单位,拥有应用程序的资源,进程包含线程,进程的资源被线程共享,线程不拥有资源. 2.前台线程和后台线程的区别? 程序关闭时,后台线程直接关闭,但前台线程 ...
- 创建多线程的第一种方式——创建Thread子类和重写run方法
创建多线程的第一种方式——创建Thread子类和重写run方法: 第二种方式——实现Runnable接口,实现类传参给父类Thread类构造方法创建线程: 第一种方式创建Thread子类和重写run方 ...
- ASP.Net Core下Authorization的几种方式 - 简书
原文:ASP.Net Core下Authorization的几种方式 - 简书 ASP.Net Core下Authorization的几种方式 Authorization其目标就是验证Http请求能否 ...
- iOS Core data多线程并发访问的问题
大家都知道Core data本身并不是一个并发安全的架构:不过针对多线程访问带来的问题,Apple给出了很多指导:同时很多第三方的开发者也贡献了很多解决方法.不过最近碰到的一个问题很奇怪,觉得有一定的 ...
- Java实现多线程的三种方式
Java多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.前两种方式启动的线程没有返回值 ...
随机推荐
- c++ 随手记
强类型的理解 先定义一些基础概念 Program Errors trapped errors.导致程序终止执行,如除0,Java中数组越界访问 untrapped errors. 出错后继续执行,但可 ...
- PAT乙级1004. 成绩排名 (20)
读入n名学生的姓名.学号.成绩,分别输出成绩最高和成绩最低学生的姓名和学号. 输入格式:每个测试输入包含1个测试用例,格式为 第1行:正整数n 第2行:第1个学生的姓名 学号 成绩 第3行:第2个学生 ...
- Office下载地址
文件名cn_office_professional_plus_2016_x86_x64_dvd_6969182.isoSHA1277926A41B472EE38CA0B36ED8F2696356DCC ...
- Ubuntu火狐、Chromium等浏览器安装flash插件
1.打开系统设置->软件和更新->其他软件,勾选Canonical合作伙伴,输入密码,重新载入更新 2.打开终端,按装插件 sudo apt install adobe-flashplug ...
- 一个数组分四个ul并且每个ul里边有四个li显示
<?php $a = $array; for($i=0;$i<4;$i++ ) {?> <ul class="new-hover"> <?php ...
- NYOJ-914 Youth的最大化(贪心)
Youth的最大化 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价值最大吗? ...
- innodb更改行格式,系统盘占用急剧升高
#大表引擎修改后,数据量较myisam引擎表大很多,对存储的行格式修改后,数据量减小. #备库修改时,由于服务器时间较早,系统盘20G,突然收到/磁盘空间占比89%的报警,立即将修改中断,恢复正常 # ...
- Webstrom 常用操作记录
WebStorm 编译 es6 与 scss 的教程: http://blog.jetbrains.com/webstorm/2015/05/ecmascript-6-in-webstorm-tran ...
- css3技巧属性之text-overflow
text-overflow:clip | ellipsis 默认值:clip 取值: clip: 当对象内文本溢出时不显示省略标记(...),而是将溢出的部分裁切掉. ellipsis: 当对象内文本 ...
- 关于并行计算的Scan操作
simple and common parallel algorithm building block is the all-prefix-sums operation. In this chapte ...