Reputation: 7234
I have noticed that when I call
[context save:nil];
the saving doesn't occur instantly. I tested that when I try to save and quit the app in one or two seconds. It only works if I keep the app open for 5+ seconds or so.
I have 2 questions:
Testing if [context save] is synchronous
I have tested that many times and this is not the behavior that I'm getting. If I have this code:
[context save:nil]
NSLog(@"Saved");
I see the "Saved" log, quit the app, and when I launch it again and try to fetch the data - nothing there. This doesn't happen if I wait about 5-10 seconds after I see the "Saved" message.
Thoughts?
Some code
- (void)storeSales:(NSArray *)sales {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"EE LLLL d HH:mm:ss Z YYYY"];
for (NSDictionary *saleDictionary in sales) {
Sale *sale = [NSEntityDescription insertNewObjectForEntityForName:@"Sale" inManagedObjectContext:self.context];
sale.productName = [saleDictionary objectForKey:@"description"];
sale.date = [formatter dateFromString:[saleDictionary objectForKey:@"occured_at"]];
NSLog(@"Stored new sale in database.");
}
[self.context save:nil];
}
How I setup the UIManagedDocument
@property (nonatomic, strong) UIManagedDocument *document;
@property (nonatomic, strong) NSManagedObjectContext *context;
...
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"SalesBot Database"];
self.document = [[UIManagedDocument alloc] initWithFileURL:url];
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.document.fileURL path]]) {
[self.document saveToURL:self.document.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {}];
} else if (self.document.documentState == UIDocumentStateClosed) {
[self.document openWithCompletionHandler:^(BOOL success) {}];
}
self.context = self.document.managedObjectContext;
UPDATE 1
I tried using NSNotificationCenter to receive NSManagedObjectContextDidSaveNotification - but - I'm receiving it twice! Once right after [context save:nil] and again 5-10 seconds later!
Upvotes: 0
Views: 1143
Reputation: 8512
So it seems like you are using UIManagedDocument
above Core Data. This explains some things.
At first, use -[UIDocument saveToURL:forSaveOperation:completionHandler:]
to save your document. From docs:
You should typically use the standard
UIDocument
methods to save the document. If you save the child context directly, you only commit changes to the parent context and not to the document store. If you save the parent context directly, you sidestep other important operations that the document performs.
UIManagedDocument
works with two managed object contexts. One is working on main thread, the second is saving changes to file in background thread. This is why your changes were saved, but after reopening were lost. The second context did not finish save operation.
This explains also why your notification was triggered two times. One for each context.
Upvotes: 3
Reputation: 8512
You can observe notification NSManagedObjectContextDidSaveNotification
.
Upvotes: 1
Reputation: 9030
The save method is not an asynchronous process. Anything that occurs after you call the save method will be executed after it has saved.
NSLog(@"About to force a save...");
[context save:nil];
NSLog(@"Now I know the save is complete!");
Upvotes: 2