核心数据数据未保存
Posted
技术标签:
【中文标题】核心数据数据未保存【英文标题】:Core data data not saved 【发布时间】:2014-01-16 09:01:54 【问题描述】:我目前正在开发一个使用 Core Data 来存储数据的应用程序。该应用程序通过下载和解析一个巨大的 XML 文件(大约 40000 个条目)将其内容与 Web 服务器同步。该应用程序允许用户搜索数据并对其进行修改 (CRUD)。提取操作太繁重,这就是我决定使用以下模式的原因:
“主线程的一个托管对象上下文 (NSMainQueueConcurrencyType) 以刷新用户界面。繁重的获取和更新是通过多个后台托管对象上下文 (NSPrivateQueueConcurrencyType) 完成的。不使用子上下文”。
我将一些对象提取到一个数组中(让我们说“用户”数组),然后我尝试在后台上下文中更新或删除一个“用户”(对象“用户”是从填充的数组中获得的)和最后我保存了那个上下文。
我正在收听 NSManagedObjectContextDidSaveNotification 并将所有修改与我的主线程托管对象上下文合并。
一切正常,除非当我重新启动我的应用程序时,我意识到没有保存任何修改。
这里有一些代码来解释使用的模式
主要托管对象上下文:
-(NSManagedObjectContext *)mainManagedObjectContext
if (_mainManagedObjectContext != nil)
return _mainManagedObjectContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
_mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_mainManagedObjectContext setPersistentStoreCoordinator:coordinator];
return _mainManagedObjectContext;
后台托管对象上下文:
-(NSManagedObjectContext *)newManagedObjectContext
NSManagedObjectContext *newContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[newContext performBlockAndWait:^
[newContext setPersistentStoreCoordinator:coordinator];
];
return newContext;
更新记录:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
FootBallCoach *coach = [_coaches objectAtIndex:indexPath.row];
coach.firstName = [NSString stringWithFormat:@"Coach %i",indexPath.row];
NSManagedObjectContext *context = [[SDCoreDataController sharedInstance] newManagedObjectContext];
[context performBlock:^
NSError *error;
[context save:&error];
if (error)
NSLog(@"ERROR SAVING : %@",error.localizedDescription);
dispatch_async(dispatch_get_main_queue(), ^
[self refreshCoaches:nil];
);
];
我错过了什么吗?我应该在保存后台上下文后保存我的主要托管对象上下文吗?
【问题讨论】:
【参考方案1】:如果您的上下文配置了持久存储协调器,那么 save 应该将数据写入存储。如果您的上下文配置了另一个上下文作为父级,那么 save 会将数据推送到父级。只有当最后一个父节点,即配置了持久存储协调器的父节点保存时,才会将数据写入存储。
-
检查您的后台上下文是否确实配置了持久存储协调器。
检查
-save:
的返回值和可能的错误。
确保您通过 -performBlock...:
方法使用背景上下文。
更新
每次调用-newManagedObjectContext
方法时,都会创建一个新上下文。这个上下文对你正在更新的 FootBallCoach 对象一无所知。您需要保存FootBallCoach 对象所属的相同上下文。
不要忘记每个对象只属于一个上下文。
还要确保你持有对正在使用其对象的上下文的强引用。
【讨论】:
我编辑了我的问题并添加了一些示例代码。如您所见,没有父子上下文模式,保存错误为零。 您每次都在创建新的上下文。更新了答案。 FootBallCoach 对象是在主上下文中获取的。所以你的意思是我应该保存主要上下文? 是的,因为每个对象只属于一个上下文。更改对象后,您需要保存其上下文,而不是另一个。 谢谢先生。我想知道您是否可以提供一些有关 Core Data 最佳实践的文档。我对遵循的最佳方法完全感到困惑。我阅读了很多文章,嵌套上下文模式存在很多性能问题。我的方法是否被认为是 fetch 和 CRUD 操作的最佳方法?我必须使用多个上下文吗? (我的应用与网络服务器同步,处理大量数据)。以上是关于核心数据数据未保存的主要内容,如果未能解决你的问题,请参考以下文章