核心数据:如何在保存文档时收到通知?

时间:2013-02-07 19:46:08

标签: ios objective-c core-data

当我打电话时,我注意到了

[context save:nil];

保存不会立即发生。当我尝试保存并在一两秒钟内退出应用程序时,我测试了它。只有当我将应用程序保持打开状态超过5秒钟时它才有效。

我有两个问题:

  • 如何知道保存何时完成?一个简单的NSLog()就足够了,仅用于测试目的。
  • 我可以强制保存吗?我应该吗?

测试[上下文保存]是否同步

我已经多次测试了,这不是我得到的行为。如果我有这个代码:

[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秒之后!

3 个答案:

答案 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