正确使用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实现有返回结果的多线程.前两种方式启动的线程没有返回值 ...
随机推荐
- css1
背景属性:background;background-color;background-image;background-repeat;(背景是否重复,有repeat-x 横式重复,repeat-y竖 ...
- metrics实践 (metrics-spring)
这里主要介绍metrics与spring集成的使用方式. 1 添加maven依赖 <dependency> <groupId>com.ryantenney.metrics&l ...
- Java代理模式汇总
简介 代理模式即Proxy Pattern,23种java常用设计模式之一.其定义为:对其他对象提供一种代理以控制对这个对象的访问. UML类图 静态代理 目标接口 public interface ...
- CodeForces 672D Robin Hood
思维. 当$k$趋向于正无穷时,答案会呈现出两种情况,不是$0$就是$1$.我们可以先判断掉答案为$1$和$0$的情况,剩下的情况都需要计算. 需要计算的就是,将最小的几个数总共加$k$次,最小值最大 ...
- [HMLY]2.CocoaPods详解----进阶
作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/19178709 转载请注明出处 一.podfile.lock文件 ...
- js的严格模式
严格模式: 严格模式这下的主要区别如下: 严格模式下的好处:
- 1. LAMP----PHP开发环境搭建(Win)
LAMP=Linux+Apache+MySQL+PHP. Step1 安装Apache http://httpd.apache.org/download.cgi 1.打开上面网址->点击File ...
- swift 中Value Type VS Class Type
ios 中Value Type 和 Class Type 有哪些异同点,这个问题是在微信的公共帐号中看到的,觉得挺有意思,这里梳理一下. 1.swift 中为什么要设置值类型? 值类型在参数传递.赋值 ...
- Zeppelin使用Spark的yarn-client模式
Zeppelin版本0.6.2 1. Export SPARK_HOME In conf/zeppelin-env.sh, export SPARK_HOME environment variable ...
- php浏览历史记录的方法
本文实例讲述了php浏览历史记录的方法.分享给大家供大家参考.具体实现方法如下: /** * 商品历史浏览记录 * $data 商品记录信息 */private function _history($ ...