iOS Core data多线程并发访问的问题
大家都知道Core data本身并不是一个并发安全的架构;不过针对多线程访问带来的问题,Apple给出了很多指导;同时很多第三方的开发者也贡献了很多解决方法。不过最近碰到的一个问题很奇怪,觉得有一定的特殊性,与大家分享一下。
这个问题似乎在7.0.1以前的版本上并不存在;不过后来我升级版本到了7.0.4。app的模型很简单,主线程在前台对数据库进行读写,而后台线程不断地做扫描(只读)。为此每个线程中各创建了一个NSManagedObjectContext。
这个模型其实有点奇怪,因为普遍的模型是颠倒过来的——后台线程做读写更新,而主线程只读;但是由于我的app的特殊性,并且读写性能并不关键,所以我并不想花很大力气去扭曲逻辑自然的结构,还是保持这个模型。不过问题也因此而来:我发现主线程写入的数据,后台线程读出来的并不一致,而是写入之前的值,即使我重新做了完整的fetch。
按照Apple文档和其他第三方资料的说明,主程序用context save后,这个改动就一定被persistent了;那么后台线程fetch怎么可能读出以前的值?机器是不会错的,既然读出的是以前的值,那么肯定是后台线程的context在哪里cache了一份。但是fetch操作无论如何应该返回persistent store里的值啊?而且insert/delete操作的修改,确实都反应出来了,唯有对property值的修改,还是旧的数值;
大量的有关并发问题的第三方讨论文章显示的是相反的问题:如果在后台线程做了修改,那么需要merge到主线程。但是这个merge影响到的只是NSFetchResultsController的内容,对于不merge造成的后果,所有的文章都众口一词:除非re-fetch或者re-fault,否则数据当然会不一致。也就是说,如果re-fetch,那么数据还是可以保持一致的。然而实际的测试证明即使是re-fetch了,还是无法反应change的数值。
最终只能怀疑re-fetch仍然不是彻底地从persistent storage里面重新load整个model。虽然insert/delete的对象确实重新load了,但是change的property确确事实没有被更新;NSManagedObjectContext 对fetch实现的机制,应该还是在内存里留了一份model的cache。为了彻底清楚这个cache,对后台线程的context进行reset后,果然一切都正常了。
iOS Core data多线程并发访问的问题的更多相关文章
- Cocos2d-x优化中多线程并发访问
多线程并发访问在Cocos2d-x引擎中用的不是很多,这主要是因为中整个结构设计没有采用多线程.源自于Objective-C的Ref对象,需要使用AutoreleasePool进行内存管理,Autor ...
- Java并发编程(03):多线程并发访问,同步控制
本文源码:GitHub·点这里 || GitEE·点这里 一.并发问题 多线程学习的时候,要面对的第一个复杂问题就是,并发模式下变量的访问,如果不理清楚内在流程和原因,经常会出现这样一个问题:线程处理 ...
- 正确使用Core Data多线程的3种方式
在#Pragma Conference 2015会议上,Marcus Zarra,撰写过关于Core Data和Core Animation的书,叙述了三种在多线程环境下使用Core Data的方法并 ...
- iOS:Core Data 中的简单ORM
我们首先在xcdatamodel文件中设计我们的数据库:例如我建立一个Data的实体,里面有一个String类型的属性name以及一个Integer类型的num: 然后选中Data,添加文件,选择NS ...
- iOS: Core Data入门
Core Data是ORM框架,很像.NET框架中的EntityFramework.使用的基本步骤是: 在项目属性里引入CoreData.framework (标准库) 在项目中新建DataModel ...
- IOS - CORE DATA的目录(xcode6)
当使用coredata作为app的后台数据存储介质后,我们很想知道数据是否成功插入.为此,我想找到coredata.sqlite的文件 代码中指定的存储目录为: - (NSURL *)appli ...
- Core Data 多线程时多个context使用
原文地址:http://blog.csdn.net/willmomo/article/details/19759413 写的非常好!我这里截取一点重要的,备份,请去原地址阅读! 本人去年10月份才接触 ...
- iOS Core Data 数据库的加密(待研究)
https://github.com/project-imas/encrypted-core-data 使用起来很方便,底层还是使用了SQLCipher,有时间要研究一下! 数据库的密码不能用固定字符 ...
- iOS-Core Data 详解
使用Core Data 框架 Core Data框架本质就是一个ORM(对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一 ...
随机推荐
- MVC 页面跳转
想要学习MVC,那么页面跳转就是必不可少的,在此我总结了常见的页面跳转方式,给自己理一下做个备份,也顺便和大家分享一下. 常见页面跳转的:(下面的视图名和控制器中的方法名一样) 在控制器内部跳转: / ...
- Part 1 What is AngularJS
What is AngularJS ? AngularJS is a JavaScirpt framework that helps build web application. AngularJS ...
- CSS之shasow(阴影)
参考https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow box-shadow属性向框添加一个或多个阴影.语法先上: box-shad ...
- 如何加密android apk
经过了忙碌的一周终于有时间静下来写点东西了,我们继续介绍android apk防止反编译技术的另一种方法.前两篇我们讲了加壳技术(http://my.oschina.net/u/2323218/blo ...
- iOS使用keychain存储密码
iOS设备中的Keychain是一个安全的存储容器.通常情况下,可以用NSUserDefaults存储数据信息,但是对于一些私密信息,比如账号.密码等等,就需要使用更为安全的keychain了.苹果自 ...
- hdu 1002大数(Java)
A + B Problem II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- (转)RabbitMQ消息队列(五):Routing 消息路由
上篇文章中,我们构建了一个简单的日志系统.接下来,我们将丰富它:能够使用不同的severity来监听不同等级的log.比如我们希望只有error的log才保存到磁盘上. 1. Bindings绑定 上 ...
- 9款完美体验的HTML5/jQuery应用
1.jQuery动画图标菜单导航 仿苹果样式 这次要分享的这款jQuery插件非常酷,它是一款带有动画按钮的jQuery菜单插件.而且从菜单的外观上来看,有点苹果菜单风格的味道.当我们将鼠标滑过菜单项 ...
- 常用的HTML 标签二
<marquee></marquee> 滚动的文字,也称"走马灯" 语法格式 <marquee 属性="属性值">内容< ...
- C++将类的构造函数、析构函数声明为private或者protected的用途
如果将构造函数.析构函数声明为private或者protected,表示不能从类的外部正常调用构造和析构函数了. 这种用法的通常使用的场景如下: 1.如果不想让外面的用户直接构造一个类A的对象,而希望 ...