Ios 核心数据:SQLite未立即更新

Ios 核心数据:SQLite未立即更新,ios,sqlite,core-data,Ios,Sqlite,Core Data,有两个实体-文档和页面。文档与页面具有一对多关系 我在添加文档时保存托管对象上下文。此时,其中没有页面。调试时,我发现writer上下文的save方法确实被调用,并且执行时没有错误。我关闭并重新打开应用程序,但找不到以前保存的文档对象。但是,如果在其中一个文档中添加一个页面,则该文档对象将显示在表中。我使用一个工具来查看SQLite文件,但我的观察并不是基于我在工具中看到的内容。即使在调试并查看文档数量时,如果文档中没有页面,也会返回0 我猜持久性存储协调器正在进行某种优化以批量写入。我可以强制

有两个实体-文档和页面。文档与页面具有一对多关系

我在添加文档时保存托管对象上下文。此时,其中没有页面。调试时,我发现writer上下文的save方法确实被调用,并且执行时没有错误。我关闭并重新打开应用程序,但找不到以前保存的文档对象。但是,如果在其中一个文档中添加一个页面,则该文档对象将显示在表中。我使用一个工具来查看SQLite文件,但我的观察并不是基于我在工具中看到的内容。即使在调试并查看文档数量时,如果文档中没有页面,也会返回0

我猜持久性存储协调器正在进行某种优化以批量写入。我可以强制它立即写入和更新持久存储吗?在对持久存储对象调用
addPersistentStoreWithType
时,是否可以添加一个选项

注意:仅供参考,我使用模式来组织托管对象上下文

解决了这个问题。以下是更新信息 所以,我一直保存整个堆栈直到编写器上下文。这只虫子很傻。我试图在主线程上保存主上下文,如下所示:

- (void)saveMainContext {
[self.mainManagedObjectContext performBlock:^{
    // Ensure that the main object context is being saved on the main queue
    __block NSError *error = nil;
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.mainManagedObjectContext save:&error];
    });
    if(!error)
    {
        //Write to disk after saving on the main UI context
        [self saveWriterContext];
    } 

}];
}
- (void)saveMainContext {
[self.mainManagedObjectContext performBlock:^{
    // Ensure that the main object context is being saved on the main queue
    dispatch_async(dispatch_get_main_queue(), ^{
        NSError *error = nil;
        [self.mainManagedObjectContext save:&error];
        if(!error)
        {
            //Write to disk after saving on the main UI context
            [self saveWriterContext];
        } 
    });
}];
}
如您所见,在尝试保存主上下文之后,我保存了writer上下文。但是,错误在于我没有等待主上下文完成保存。修复错误后,我的代码如下所示:

- (void)saveMainContext {
[self.mainManagedObjectContext performBlock:^{
    // Ensure that the main object context is being saved on the main queue
    __block NSError *error = nil;
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.mainManagedObjectContext save:&error];
    });
    if(!error)
    {
        //Write to disk after saving on the main UI context
        [self saveWriterContext];
    } 

}];
}
- (void)saveMainContext {
[self.mainManagedObjectContext performBlock:^{
    // Ensure that the main object context is being saved on the main queue
    dispatch_async(dispatch_get_main_queue(), ^{
        NSError *error = nil;
        [self.mainManagedObjectContext save:&error];
        if(!error)
        {
            //Write to disk after saving on the main UI context
            [self saveWriterContext];
        } 
    });
}];
}

而且,这解决了问题!我犯了一个非常愚蠢的错误。

你确定要保存整个堆栈吗?如果在私有上下文中进行更改,则需要保存该私有上下文。如果在主上下文(从UI)中进行更改,则需要保存该上下文。只有在所有其他上下文都向
报告了
NO
之后,您才应该保存编写器上下文(即其设计中的主上下文)

我想这是你的问题

对OP的回应
嗯,我不知道。谢谢那么,你是说如果我根本不检查“错误”,只检查save的返回,我可能会过得很好吗

我想说的是,您的保存应该是这样的(注意,我还纠正了您不必要的调度\u async):

dispatch\u async
将被忽略,因为您已经在正确的队列中


调用
-save:
返回一个
bool
。如果和如果返回
您是否对
错误作出反应

谢谢Marcus!我检查了整个堆栈,确保按照您的建议顺序保存上下文,并找到了bug。非常感谢!是的,我应该在我的保存方法中添加hasChanges。并且在保存后不要检查错误。你跟踪的作者不正确。检查
-save:
中的返回并对此作出响应。即使没有错误发生,也可以填充错误。Hmm。我不知道。谢谢那么,你是说如果我根本不检查“错误”,只检查save的返回,我可能会过得很好吗?更新的答案澄清了我对
错误的评论。