zoukankan      html  css  js  c++  java
  • 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后,果然一切都正常了。

  • 相关阅读:
    java.util.date java.sql.date java.sql.timestamp
    javadoc生成文档时,编码 GBK 的不可映射字符
    java关于ServletConfig FilterConfig什么用
    在项目中用run as java aplication调试类
    replace和replaceAll
    在easyui中的datagrid中使用行内编辑时textarea的换行保存到mysql数据库为\n
    [转] 设计模式另类版
    [转] 不错的俄罗斯方块程序代码(VC++版)
    [转] 30道模拟经典题(JDK1.4)(附解答)
    [转] C#排序算法
  • 原文地址:https://www.cnblogs.com/rolandash/p/3769127.html
Copyright © 2011-2022 走看看