Core Data 多线程操作实战篇
最近在解决百度音乐iPhone客户端偶现数据库操作crash的问题,顺手整理了下CoreData的多线程原则,以及实际开发时应该如何遵守这些原则。
Core Data多线程操作的基本原则
- 不允许跨线程访问MOC: 在某一个MOC上的CRUD操作只能在它的操作线程上进行
- 不允许跨线程访问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给出的原因是:
- Core Data已经废弃了confinement context
- Core Data中新的queue context内部使用serial dispatch_queue来保证线程安全
- MR中的
-MR_contextForCurrentThread
方法是把一个queue context存储在一个thread的字典里。这样会导致调用这个方法的线程一定不是queue context的操作线程.
我是这么理解的:
- 我们使用
-MR_contextForCurrentThread
这个方法通常的习惯是,拿到这个方法返回的context之后,直接在这个context上进行CRUD操作。这在旧版本使用confinement context的Core Data是没有问题的。因为这个confinement context的创建线程就是它的合法操作线程 - 对于queue context, 如果我们继续按照1中的方式使用这个context是有问题。原因就是tonyarnold给出的第三点。正确的做法应该是把CRUD操作都放在
-performBlock:
或-performBlockAndWait:
中 - 我认为,如果我们能用正确的方式使用
-MR_contextForCurrentThread
方法返回的context, 那么是没有问题的
App中应该如何遵守Core Data的多线程操作原则
如果你App也使用了Magical Record, 那么建议你按照官方说明上的方式替换掉它打算废弃的API。比如用每次创建一个新的-MR_context
的方式来替换掉-MR_contextForCurrentThread
的使用。
下面是我在修改百度音乐iPhone客户端的数据库操作时总结的几个方法:
每个入参有MO的方法
- 自己保证(不是由调用者保证)对MO的访问和修改在MO.managedObjectContext的操作线程上执行
- 此方法应该仅把DB操作放在MO.managedObjectContext的操作线程上。 这么要求是为了避免修改数据库操作之外的任务的线程安排
- 注意,不要把FRC.fetchedObjects作为参数传递。对这个数组做遍历、或者取大小等的操作必须要在FRC.managedObjectContext中进行,而仅由传入的FRC.fetchedObjects无法获取此信息
- MO的category中的方法
- -方法,没有必要用
-performBlock:
或-performBlockAndWait:
包起来。因为调用者应该有这样的意识:对MO的操作需要在它所属的MOC上进行。这点和CoreData的要求是一致的 - +方法需要自己保证不违反线程操作原则。 这点和MagicalRecord保持一致
- -方法,没有必要用
Core Data有关的Debug方式
- -com.apple.CoreData.ConcurrencyDebug 3
- -com.apple.CoreData.SQLDebug 3
- -com.apple.CoreData.SyntaxColoredLogging YES
转载于:https://www.cnblogs.com/mindyme/p/5089454.html
Core Data 多线程操作实战篇相关推荐
- ios并发会造成什么问题_iOS Core data多线程并发访问的问题
大家都知道Core data本身并不是一个并发安全的架构:不过针对多线程访问带来的问题,Apple给出了很多指导:同时很多第三方的开发者也贡献了很多解决方法.不过最近碰到的一个问题很奇怪,觉得有一定的 ...
- 正确使用Core Data多线程的3种方式
在#Pragma Conference 2015会议上,Marcus Zarra,撰写过关于Core Data和Core Animation的书,叙述了三种在多线程环境下使用Core Data的方法并 ...
- linux单个core的线程,正确使用Core Data多线程的3种方式
在 #Pragma Conference 2015 会议上,Marcus Zarra,撰写过关于 Core Data 和 Core Animation 的书, 叙述 了三种在多线程环境下使用 Core ...
- ASP.NET Core 快速入门(实战篇)
上篇讲了<asp.net core在linux上的环境部署>.今天我们将做几个小玩意实战一下.用到的技术和工具有mysql.websocket.AngleSharp(爬虫html解析).n ...
- 深入浅出学习透析 Nginx 服务器的基本原理和配置指南「运维操作实战篇」
Nginx前提回顾 Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性: Web服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效 ...
- Core Data数据操作
1.建立学生实体,插入100条数据 2.按条件查询学生数据 3.统计学生信息 4.修改学生信息 5.删除学生数据 import UIKit import CoreData class ViewCont ...
- 谈谈用SQLite和FMDB而不用Core Data
谈谈用SQLite和FMDB而不用Core Data 发布于:2014-04-22 11:22阅读数:4235 凭良心讲,我不能告诉你不去使用Core Data.它不错,而且也在变好,并且它被很多其他 ...
- 我为什么用 SQLite 和 FMDB 而不用 Core Data
转:http://segmentfault.com/a/1190000000363392 编者注:文章的"我"是指原作者. 凭良心讲,我不能告诉你不去使用Core Data.它不错 ...
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
深入浅出 Cocoa 之 Core Data(1)- 框架详解 罗朝辉(http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 Core data 是 Cocoa 中处 ...
最新文章
- 服务器监控系统的介绍,客户服务系统服务器监控系统
- beta 圆桌桌 4
- 在Kotlin中使用libGDX
- shiro学习(5):ini文件和自定义realm
- 如何使用 IntelliJ IDEA 2017 配置PHP开发环境 及项目搭建
- html让文本框左剧中对齐_Python—Text:功能强大的文本框
- JAVA控制台扑克牌游戏,洗牌,发牌,比较大小
- 阿里云云计算 44 云计算常见威胁
- MATLAB编程实例
- 数据库缓存一致性解决方案
- EXCEL如何将平均值加减标准差设置为科学计数法显示
- MySql基础篇之SQL语句(DDL、DML、DQL、RCL)
- vue图片宽高自适应_Vue组件宽高自适应问题
- 第二章 编程初步 Ivor Horton
- AR/VR技术在旅游业+零售业的应用
- 0622_ArcMap添加地图地图(矢量底图与影像地图)_太乐地图插件ArcTailer.tlb
- LSTM trick之LSTMP
- 无线通讯 cmt2150A 简介 1527协议
- 用Python进行图文识别(OCR)
- 窗口无故失去焦点解决方案