iOS Core data多线程并发访问的问题

时间:2021-07-26 14:33:08

大家都知道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. AndroidStudio Rename Package

    AndroidStudio中重命名包名的方法和可能遇到的问题 在开发中,可能会遇到需要重命名和合并某个包的情况.如果进行如下操作可能会导致以下结果: 在一个空包下创建一个包,会出现两个包名合并的情况. ...

  2. SqlDataReader对象的NextResult方法读取存储过程多个结果集

    如上图,我这里有返回4个记录集,分别表示 发送的总数,成功数,失败数,以及所有的记录集,那么我怎么去获取呢? 如果我第二个记录集 第三个记录集 都是多行的话,怎么办?可以参考下面这张图

  3. Enum(枚举)示例

    package main; public class EnumTest { /**     * 普通枚举     */    public enum ColorEnum {        red, g ...

  4. cf E. Dima and Magic Guitar

    http://codeforces.com/contest/366/problem/E |x1-x2|+|y1-y2|有四种情况 1.-(x1-x2)+(y1-y2); 2.(x1-x2)-(y1-y ...

  5. c#提出中文首字母

           ; i < len; i++)             {                 myStr += getSpell(strText.Substring(i, ));   ...

  6. Mac OS X Yosemite安装Hadoop 2&period;6记录

    整个安装过程分为四部分: 一.  安装Homebrew 二.  ssh localhost 三. 安装Hadoop已经进行配置文件设置 (伪分布式) 四. 执行栗子 一. 安装Homebrew 採用H ...

  7. Excel一项研究指出色彩

    Excel一项研究指出色彩 从Office2007跳到了2013版本号,尽管有着种种不适,但应该承认Excel2013版本号在图表和色彩上更加人性化和"专业"了一些. 但假设须要更 ...

  8. oracle数据库全然恢复和不全然恢复以及运行用户管理辈分恢复

    比較全然恢复和不全然恢复: 一.全然恢复:将数据库恢复到当前最新状态,包含直至请求恢复时进行的全部已提交的数据更改 二.不全然恢复:将数据库恢复到请求恢复操作之前指定的过去时间点 一.全然恢复过程 以 ...

  9. Linux 解决 bash &period;&sol; 没有那个文件或目录 的方法

    在Debian 或 ubuntu 64位下运行 ./xxx 会跳出来说没有这个文件或者目录,但是ls看又有这个文件,很是奇怪. 其实原因很简单,是因为他没有32位的运行库 ia32-libs ,直接安 ...

  10. 关于dede后台登陆后一片空白以及去除版权

    今天家里的电脑上新装DEDE5.7后台登陆后竟然一片空白,装PHPCMS却没有问题.百度了好久,也没找到一个像样的答案,晕死! 看了源码后发现在源码里的类库中很多都是PHP4的语法,var这个函数在P ...