当我打电话时,我注意到了
[context save:nil];
保存不会立即发生。当我尝试保存并在一两秒钟内退出应用程序时,我测试了它。只有当我将应用程序保持打开状态超过5秒钟时它才有效。
我有两个问题:
测试[上下文保存]是否同步
我已经多次测试了,这不是我得到的行为。如果我有这个代码:
[context save:nil]
NSLog(@"Saved");
我看到“保存”日志,退出应用程序,当我再次启动它并尝试获取数据时 - 没有任何内容。 如果我在看到“已保存”消息后等待大约5-10秒后,就不会发生这种情况。
思想?
部分代码
- (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];
}
我如何设置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;
更新1
我尝试使用NSNotificationCenter接收NSManagedObjectContextDidSaveNotification - 但是 - 我收到了两次!在[context save:nil]之后,再过5-10秒之后!
答案 0 :(得分:3)
因此,您似乎使用核心数据上方的UIManagedDocument
。这解释了一些事情。
首先,使用-[UIDocument saveToURL:forSaveOperation:completionHandler:]
保存文档。来自docs:
您通常应使用标准
UIDocument
方法来保存文档。 如果直接保存子上下文,则仅提交对父上下文的更改,而不是文档存储。如果直接保存父上下文,则可以回避文档执行的其他重要操作。
UIManagedDocument
适用于 两个 托管对象上下文。一个是在主线程上工作,第二个是在后台线程中保存对文件的更改。这是为什么您的更改已保存,但重新打开后丢失。第二个上下文未完成保存操作。
这也解释了为什么您的通知被触发了两次。每个背景一个。
答案 1 :(得分:2)
保存方法不是异步进程。调用save方法后发生的任何事情都将在保存后执行。
NSLog(@"About to force a save...");
[context save:nil];
NSLog(@"Now I know the save is complete!");
答案 2 :(得分:1)
您可以观察通知NSManagedObjectContextDidSaveNotification
。