问题
In the MagicalRecord github docs it states:
MagicalRecord provides a background saving queue so that saving all data is performed off the main thread, in the background. This means that it may be necessary to use MR_saveNestedContexts rather than the typical MR_save method in order to persist your changes all the way to your persistent store.
looking at the source, I can't figure out the difference between these two methods minus the dispatch_async
command. I see that they both save all nested contexts up to the root, therefore persisting to the store. But why and in what situation would I use one over the other?
Also, as far as just saving a nested context up one level (without persisting to store) I'm assuming I would still use NSManagedObjectContext's - (BOOL)save:(NSError **)error
method?
Below is the source code of the two methods.
- (void) MR_save {
[self MR_saveErrorHandler:nil];
}
- (void) MR_saveErrorHandler:(void (^)(NSError *))errorCallback {
[self performBlockAndWait:^{
[self MR_saveWithErrorCallback:errorCallback];
if (self.parentContext) {
[[self parentContext] performBlockAndWait:^{
[[self parentContext] MR_saveErrorHandler:errorCallback];
}];
}
}];
}
- (void) MR_saveNestedContexts {
[self MR_saveNestedContextsErrorHandler:nil];
}
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback {
[self MR_saveNestedContextsErrorHandler:nil completion:nil];
}
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion {
[self performBlock:^{
[self MR_saveWithErrorCallback:errorCallback];
if (self.parentContext) {
[[self parentContext] performBlock:^{
[[self parentContext] MR_saveNestedContextsErrorHandler:errorCallback completion:completion];
}];
} else {
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion();
});
}
}
}];
}
回答1:
With the new Parent/Child feature in CoreData from iOS5 and Lion on up, it is sometimes necessary to "force" a save all the way to disk. That is, when you have, for example, 3 contexts, such as:
root <- child1 <- child2
If you save in child2, those changes are only notified up a single level to child1. Root won't have them. In order to do this, you must call save one more time. The fact that you can have an arbitrarily long list of these contexts means you won't know if your save ever gets to the root context, which also is responsible for persisting changes to the store (disk). saveNestedContexts uses recursion to traverse this tree and make sure your save actually goes to disk, when you intended it to do so.
回答2:
The similarity between 'MR_save' and 'MR_saveNestedContexts' was changed in version 2.0.8 (I was using 2.0.7).
Here is the commit on github: https://github.com/magicalpanda/MagicalRecord/commit/f7c4350e9daf7d90eec83ba5eafeccfa7af34312
And the discussion: https://github.com/magicalpanda/MagicalRecord/issues/305
So to summarize, in version 2.0.8, 'MR_save' now only saves the current context, and 'MR_saveNestedContexts' recursively saves up to the topmost context.
来源:https://stackoverflow.com/questions/13300129/regarding-magicalrecord-what-is-the-difference-between-the-methods-mr-saveneste