大家好我正在开发一个使用coredata(多线程)的应用程序,下面是使用的coredata堆栈(这是通过这里的教程设计的:https://www.cocoanetics.com/2012/07/multi-context-coredata/)
模特
- (NSManagedObjectModel *)managedObjectModel {
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"XXX" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
主要背景
- (NSManagedObjectContext *)managedObjectContext{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_managedObjectContext.parentContext = [self writerManagedObjectContext];
return _managedObjectContext;
}
作家背景
- (NSManagedObjectContext *)writerManagedObjectContext{
if (_writerManagedObjectContext != nil) {
return _writerManagedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_writerManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_writerManagedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _writerManagedObjectContext;
}
持久的商店评论
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"XXX.sqlite"];
NSError *error = nil;
NSString *failureReason = @"There was an error creating or loading the application's saved data.";
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:@"XXX" URL:storeURL options:options error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
如您所见,WRITER上下文是MAIN上下文的父级,这意味着WRITER将处理将数据保存到存储,同时它还更新任何更改的MAIN上下文(在内存中)。
注意:WRITER保存到商店,因为POS已设置为WRITER上下文。
在模型中的实体上,我将'Id'设置为数据库中用于UPSERT的所有实体(表)的唯一约束(即等同于SQL insert OR replace
)。
MAIN和WRITER上下文都将其合并策略设置为NSMergeByPropertyObjectTrumpMergePolicy
,以确保WRITER,MAIN和商店之间的对象同步。
[[CoreDataCommons mainContext] setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[[CoreDataCommons writerContext] setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
现在,当我想插入数据库时,我创建了一个新的上下文:
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[context setParentContext:writerManagedObjectContext];
[context performBlock:^{
// Populate entity attributes and save
for (id object in objects){
// Save every 500 objects
if (count % 500 == 0){
if ([context save:&error]){
}
}
count++;
}
// Final save if anything unsaved
if ([context save:&error]){
}
// Save WRITER context which will push changes to MAIN context
[writerManagedObjectContext performBlock:^{
if (![writerManagedObjectContext save:&writerError]) {
DLog(@"Writer: Unresolved error %@, %@", writerError, [writerError localizedDescription]);
}];
}];
问题
当第一次加载应用程序时,它会从API加载大约15000个对象(类型JSON),它会在大约3秒内写入这些数据(我认为这有点太长但不是主要问题);但第一次加载不是问题。 ISSUE来自API的后续加载;因此,第二次加载它需要大约5分钟来写相同的数据,它也会阻止主线。
经过一些调试后,我发现当数据库中已存在数据时,约束(即UPSERT)会导致保存时间过长。这意味着它还做了它的原始性
IF (EXIST){ // UPDATE}ELSE{ // INSERT}
我已经使用了多个上下文来确保不是这种情况,但它似乎仍然保留了主线程并且需要花费大量时间来保存。
问题 首先,是否会出现coredata堆栈引起的任何问题(即死锁,后台进程等)?
其次:是否需要用coredata保存对象的正常时间?如果没有,任何人都可以提出优化策略。
第三,我正在考虑绕过coredata并直接使用sqlite。有任何预见的障碍吗?除了coredata提供的安全层。
欢迎任何想法。
提前致谢。