有时,我注意到ManagedObjectContext的“ save:”操作永远不会返回并消耗100%的CPU。

我在GarbageCollected环境(Mac OS X 10.6.3)中使用SQL Store。磁盘活动显示约700 KB / s的写入速度。在查看包含sqlite数据库文件的文件夹时,“-journal”文件出现并消失,出现并消失,...

这是来自过程分析的调用图的一部分:

  2203 -[NSManagedObjectContext save:]
    1899 -[NSPersistentStoreCoordinator(_NSInternalMethods) executeRequest:withContext:]
      1836 -[NSSQLCore executeRequest:withContext:]
        1836 -[NSSQLCore saveChanges:]
          1479 -[NSSQLCore performChanges]
            ...
          335 -[NSSQLCore recordChangesInContext:]
            ...
          20 -[NSSQLCore rollbackChanges]
            ...
          2 -[NSSQLCore prepareForSave:]
            ...
      62 -[NSPersistentStoreCoordinator(_NSInternalMethods) _checkRequestForStore:originalRequest:andOptimisticLocking:]
        ...
      1 -[NSPersistentStore(_NSInternalMethods) _preflightCrossCheck]
        ...
    184 -[NSMergePolicy resolveConflicts:]
      ...
    120 -[NSManagedObjectContext(_NSInternalChangeProcessing) _prepareForPushChanges:]
      ...


一切都在主GUI线程中发生。

有什么想法可以解决这个问题吗?

最佳答案

感谢Marcus给您的提示,这是一个循环!但是,此循环不是由通知的观察者引起的。

循环的原因是CoreData中的一个错误(我认为是一个错误):在这种情况下保存的实体之一的属性类型为Double。并且属性值已更改。因此,CoreData将存储的值与缓存的值进行比较,有时十进制数字会导致CoreData NSSQLCore“认为”存储的值已从外部更改。

通常,这将导致save:方法失败并返回NSError,但在我的情况下,将NSManagedObjectContext配置为使用NSMergeByPropertyObjectTrumpMergePolicy合并策略。因此,由于CoreData错误地认为存在外部更改,因此它仅获取内存中的属性值(具有一些“不利”的数字)并将其存储。之后,它将存储的值与内存中的值进行比较,并再次检测不等式并执行回滚并再次存储该值-这就是循环。

由于我强制Double属性存储包含整数值的NSNumber对象,因此save:成功。

此链接link text帮助我找到了答案。

我不是CoreData专家,所以我不确定所有解释是否正确。

关于sqlite - 无休止地保存核心数据上下文,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2935579/

10-11 22:59
查看更多