正确使用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实现有返回结果的多线程.前两种方式启动的线程没有返回值 ...
随机推荐
- POI插件使用读取office文件
html文件代码如下: <!doctype html> <html> <head> <meta charset="utf-8"> & ...
- PXE+kickstart自动安装ubuntu14.04
本文参考了诸多文章,先感谢这些文章的作者. 使用pxe安装系统需要安装dhcp,tftp,http等服务(当然也可以使用其他文件共享方式比如nfs,ftp). 实验环境: 1. vmware 12 2 ...
- POJ 2104:K-th Number(整体二分)
http://poj.org/problem?id=2104 题意:给出n个数和m个询问求区间第K小. 思路:以前用主席树做过,这次学整体二分来做.整体二分在yr大佬的指点下,终于大概懂了点了.对于二 ...
- RF环境安装-mac-osx10.10-基础环境-安装指南
一.适用环境: mac系列,osx10.10,自带Python 二.简要步骤: 1. 安装pip,mac自带Python环境,所以我们改成安装pip 2. 安装wxPython,此处我下载的版本是wx ...
- [ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp
题意: 有一块n*m的土地 0代表不肥沃不可以放牛 1代表肥沃可以放牛 且相邻的草地不能同时放牛 问最多有多少种放牛的方法并对1e8取模 思路: 典型的状压dp 能状态压缩 能状态转移 能状态压缩的题 ...
- Elasticsearch .net 客户端条件拼接查询
private Func<SearchDescriptor<BaseTest>, ISearchRequest> ConstructWhere(TestCondition wh ...
- jquery一个简单的菜单小插件
刚学会封装插件,先来封装一个小的菜单插件 html部分 <ul class="zong"> <li class="yiji"> < ...
- bfs或者dfs Good Bye 2016 D
http://codeforces.com/contest/750/problem/D 题目大意: 放鞭炮,鞭炮会爆炸n次,每次只会往目前前进方向的左上和右上放出他的子鞭炮.问,最后能有多少格子被覆盖 ...
- linux下安装LoadRunner LoadGenerator
root用户登录 关闭防火墙: setenforce 0 /etc/init.d/iptables stop 先安装一个rpm包,compat-libstdc++-33-3.2.3-61.i386.r ...
- Java中新建子文件夹和新建文件
File file = new File("地址"); file.mkdirs(); //新建文件夹,当没有父文件夹时,但是不会自动创建父文件夹 file.mkdirs(); // ...