Core Data - Saving to persistant store on disk in the background
I'm hoping someone will be able to provide a quick answer to this one, it will probably be a really obvious one, but I just can't get my head around it.
I have an app, for the mac, in which I am using Core Data to save information. All that is working fine, and when I create new data it shows up in the app fine, and when I quit the app, [managedObjectContext save:&error] is called successfully and the data is stored to the persistent store on disk.
What I am looking to do is to save to core data any time any information is changed. The reasoning behind this is to prevent any data loss should the app cras开发者_开发问答h, and because I will be giving the users the option to store on dropbox/idisk, it would just be nice to have the information saved immediately as then changes should show up on other computers that they are accessing the same data on.
So far, I have found the following using NSNotificationCenter:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(saveDatabaseInBackground)
name:NSManagedObjectContextObjectsDidChangeNotification
object:managedObjectContext];
Which, whenever data is changed, successfully calls:
- (void) saveDatabaseInBackground
{
NSError *error = nil;
if ([managedObjectContext hasChanges])
{
[managedObjectContext save:&error];
}
}
However it seems that calling the save method on the managed object context results in the same notification being posted, resulting in an infinite loop and causing a crash.
Anyone have any ideas on how to resolve?
Thanks,
Rob
There is no resolution for using that notification to save your managed object. The NSManagedObjectContextObjectsDidChangeNotification is posted during processPendingChanges, after the changes have been processed, but before it is safe to call save. If you try, you will generate an infinite loop -- as you have discovered. This is mentioned in the documentation on the notification.
Your requirement is to auto-save data so that nothing is lost during a crash. I went through a similar process for my app -- which is in the top 50 in the app store in productivity and also includes dropbox syncing -- and determined that in most use cases I studied an almost immediate save of changed data is generally good enough. Instead of trying to save the instant anything on the object is changed, why not check for changes every n seconds and save if necessary? Set up a timer and check your object for isUpdated. It's fairly straightforward, but there are a few gotchas you need to watch for such as not attempting a save if a save is already in progress. This is particularly important when syncing to services like dropbox which can take a significant amount of time to sync.
If you need more detailed code on setting up a timer, checking the managed object and saving I'll be happy to do so.
精彩评论