开发者

Endless saving of CoreData Context

Sometimes I noticed that a 'save:' operation an a ManagedObjectContext never returns and consumes 100% CPU.

I'm using an SQL Store in a GarbageCollected environment (Mac OS X 10.6.3). The disk activity shows about 700 KB/s writing. While having a look at the folder that contains the sqlite database file the "-journal" file appears and disappears, appears 开发者_StackOverflow社区and disappears, ...

This is part of the call graph from the process analysis:

  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:]
      ...

Everything a happening in the main GUI thread.

Any ideas what I can to do to resolve the problem?


Thanks Marcus for your hint that this is a loop! But this loop wasn't caused by an observer for a notification.

The reason for the loop is an bug (I think it is one) in CoreData: One of the entities that are saved in this situation has a property of type Double. And the property value was changed. So CoreData compares the stored value with the cached value and sometimes the decimal digits causes CoreData NSSQLCore to "think" that the stored values was changed from outside.

Normally this would cause the save: method to fail and return an NSError but in my case a configured the NSManagedObjectContext to use the NSMergeByPropertyObjectTrumpMergePolicy merge policy. So because CoreData falsely thinks that there was an external change it just takes the in-memory property value (that has some "unfavorable" digits) and stores that. After that it compares the stored value with the in-memory value and again detects an inequality and performs an rollback and stores the value again - that's the loop.

Since I force the Double property to store NSNumber objects that contain integer values, the save: is successful.

This link link text helped me to find the out.

I'm NOT an CoreData specialist so I'm not sure if everything was explained correctly.


Clearly you most likely have a loop. Are you monitoring or reacting to the NSNotification being broadcast by the NSManagedObjectContext? That is usually the only thing that will cause a loop like this.

Are you using any threading?

Update

Turn off your observer of the save and see if the loop still exists. Without seeing your code that is the best guess as to the cause of your loop.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜