0

我注意到当我打电话时

[context save:nil];

保存不会立即发生。当我尝试在一两秒内保存并退出应用程序时,我对此进行了测试。仅当我将应用程序保持打开 5 秒左右时它才有效。

我有两个问题:

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

测试 [context save] 是否同步

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

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

4

3 回答 3

3

所以看起来你正在使用UIManagedDocument上面的核心数据。这解释了一些事情。

首先,用于-[UIDocument saveToURL:forSaveOperation:completionHandler:]保存您的文档。来自文档:

您通常应该使用标准UIDocument方法来保存文档。如果您直接保存子上下文,您只会将更改提交到父上下文而不是文档存储。如果您直接保存父上下文,您将回避文档执行的其他重要操作。

UIManagedDocument使用两个托管对象上下文。一是在主线程上工作,二是在后台线程中保存对文件的更改。这就是您的更改已保存但重新打开后丢失的原因。第二个上下文没有完成保存操作。

这也解释了为什么您的通知被触发了两次。每个上下文一个。

于 2013-02-07T20:21:59.880 回答
2

save 方法不是一个异步过程。调用 save 方法后发生的任何事情都将在保存后执行。

NSLog(@"About to force a save...");
[context save:nil];
NSLog(@"Now I know the save is complete!");
于 2013-02-07T19:49:01.253 回答
1

您可以观察通知NSManagedObjectContextDidSaveNotification

于 2013-02-07T19:55:23.423 回答