大家都知道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多线程并发访问的问题的更多相关文章

  1. Cocos2d-x优化中多线程并发访问

    多线程并发访问在Cocos2d-x引擎中用的不是很多,这主要是因为中整个结构设计没有采用多线程.源自于Objective-C的Ref对象,需要使用AutoreleasePool进行内存管理,Autor ...

  2. Java并发编程(03):多线程并发访问,同步控制

    本文源码:GitHub·点这里 || GitEE·点这里 一.并发问题 多线程学习的时候,要面对的第一个复杂问题就是,并发模式下变量的访问,如果不理清楚内在流程和原因,经常会出现这样一个问题:线程处理 ...

  3. 正确使用Core Data多线程的3种方式

    在#Pragma Conference 2015会议上,Marcus Zarra,撰写过关于Core Data和Core Animation的书,叙述了三种在多线程环境下使用Core Data的方法并 ...

  4. iOS:Core Data 中的简单ORM

    我们首先在xcdatamodel文件中设计我们的数据库:例如我建立一个Data的实体,里面有一个String类型的属性name以及一个Integer类型的num: 然后选中Data,添加文件,选择NS ...

  5. iOS: Core Data入门

    Core Data是ORM框架,很像.NET框架中的EntityFramework.使用的基本步骤是: 在项目属性里引入CoreData.framework (标准库) 在项目中新建DataModel ...

  6. IOS - CORE DATA的目录(xcode6)

       当使用coredata作为app的后台数据存储介质后,我们很想知道数据是否成功插入.为此,我想找到coredata.sqlite的文件 代码中指定的存储目录为: - (NSURL *)appli ...

  7. Core Data 多线程时多个context使用

    原文地址:http://blog.csdn.net/willmomo/article/details/19759413 写的非常好!我这里截取一点重要的,备份,请去原地址阅读! 本人去年10月份才接触 ...

  8. iOS Core Data 数据库的加密(待研究)

    https://github.com/project-imas/encrypted-core-data 使用起来很方便,底层还是使用了SQLCipher,有时间要研究一下! 数据库的密码不能用固定字符 ...

  9. iOS-Core Data 详解

    使用Core Data 框架 Core Data框架本质就是一个ORM(对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一 ...

随机推荐

  1. C# 线程抛异常

    异常抛出 异常抛出要在线程代码中抛出,否则捕获不到 using System; using System.Threading; namespace testthread_keyword_lock { ...

  2. Java之简单图形面积计算

    设计一个类层次,定义一个抽象类--形状(类名:shape).其中包括求形状的面积抽象方法(方法名:calArea()).继承该抽象类定义三角形(Triangle).矩形(Rectangle).圆(Ci ...

  3. [老老实实学WCF] 第一篇 Hello WCF

    老老实实学WCF  第一篇 Hello WCF WCF(Windows Communication Foundation)是微软公司推出的面向服务技术的集大成者,涵盖继承了其之前发布的所有的分布式应用 ...

  4. 第二篇、Swift_自定义 tabbar 的 badgeValue显示样式

    在实际的开发中,我们常常需要根据实际的需求,去改变bageValue的显示样式,默认是红色的背景,白色的字体颜色 使用方式: class BKTabBarController: UITabBarCon ...

  5. 《Cocos2d-x实战 Lua卷》上线了

    感谢大家一直以来的支持!各大商店均开始销售:京东:http://item.jd.com/11659697.html当当:http://product.dangdang.com/23659810.htm ...

  6. Professional iOS Network Programming Connecting the Enterprise to the iPhone and iPad

    Book Description Learn to develop iPhone and iPad applications for networked enterprise environments ...

  7. 理解C#系列 / 核心C# / 名称空间

    名称空间namespace 名称空间 名称空间用来逻辑分类,而不是物理上的,名称空间与程序集无关[程序集:经由编译器编译得到的文件],同一个程序集中可以有2不同的名称空间,也可以在不同的程序集中定义同 ...

  8. 完美解决移动Web小于12px文字居中的问题

    前几天的一篇博文:移动Web单行文字垂直居中的问题,提到了移动web里小于12px的文字居中异常的问题,最后还是改为12px才近乎解决了问题.但是有时候或许并不是那么乐观,你并不能将原本定为10px的 ...

  9. CSS制作彩虹效果

    今天看到一篇文章,说到margin的塌陷的问题,并提供了好几个例子. 自己之前还没怎么遇到过这个问题,正好来研究一下. <div class="box1"></d ...

  10. 反射-Reflect

    1.得到一份Class(同一个类在JVM中只有一份字节码) 三种方式:类名.class, Class.forName("全限定名");, 对象.getClass(); 基本类型 i ...