我正在尝试在后台上下文中执行Core-data操作。 我在后台上下文中插入了所有数据,但是当我在主线程上访存时,它不会显示任何已经插入的数据。 我不知道我在哪里犯错... :( 任何帮助表示赞赏。
这是我尝试插入的内容,第二个是获取数据的内容。
- (void)insertNameAndSurnameInDataBase:(NSString *)name surname:(NSString *)surname numbers:(NSArray *)numbers labels:(NSArray *)labels {
AppDelegate *appDel=(AppDelegate *)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *saveObjectContext = [appDel saveManagedObjectContext];
NSManagedObjectContext *bgContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
bgContext.parentContext = saveObjectContext;
[bgContext performBlockAndWait:^{
NSError *error;
NameAndSurname *nameAndSurname = [NSEntityDescription insertNewObjectForEntityForName:@"NameAndSurname" inManagedObjectContext:bgContext];
NSString *nSurname = [NSString stringWithFormat:@"%@ %@",name,surname];
if (nSurname.length == 0) {
nameAndSurname.nameSurname = [numbers objectAtIndex:0];
} else {
nameAndSurname.nameSurname = nSurname;
}
if ([bgContext save:&error]) {
} else {
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"NameAndSurname" inManagedObjectContext:bgContext];
// predicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"nameSurname =[c] %@", nSurname];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSArray *fetchedObjects = [bgContext executeFetchRequest:fetchRequest error:&error];
if([fetchedObjects count] > 0){
[numbers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
id obj2 = [labels objectAtIndex:idx];
obj = [obj stringByReplacingOccurrencesOfString:@" " withString:@""];
ContactNumber *phoneNumber = [NSEntityDescription insertNewObjectForEntityForName:@"ContactNumber" inManagedObjectContext:bgContext];
phoneNumber.number = obj;
phoneNumber.label = obj2;
phoneNumber.nameAndSurname = fetchedObjects[0];
NSError *error;
if ([bgContext save:&error]) {
} else {
}
}];
}
}];
}
- (NSArray *)fetchNameAndSurname {
AppDelegate *appDel = (AppDelegate *)[UIApplication sharedApplication].delegate;
_managedObjectContext = [appDel managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"NameAndSurname"
inManagedObjectContext:_managedObjectContext];
[fetchRequest setSortDescriptors:@[[[NSSortDescriptor alloc] initWithKey:@"nameSurname" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]]];
[fetchRequest setEntity:entity];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSError *error = nil;
NSArray *fetchedObjects = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
return [fetchedObjects valueForKey:@"nameSurname"];
}
答案 0 :(得分:0)
您犯的错误是不测试该代码的许多小片段,这些小片段可能无法按预期工作。要解决此类问题,您必须从头开始并一次测试一个。我看到的第一个问题是托管对象上下文之间的混乱……
看来,方法saveManagedObjectContext
是主托管对象上下文的吸气剂。用英语, save 是一个动词,因此此方法名称表示它正在保存某些托管对象上下文。如果我没错,您应该将名称saveManagedObjectContext
更改为mainMangaedObjectContext
。
语句_managedObjectContext = [appDel managedObjectContext]
是非常不标准的,它从看起来像它的吸气剂的位置分配一个实例变量。如果像往常一样,_managedObjectContext
是支持属性managedObjectContext
的实例变量,则此语句无效。
在第一种方法中,您使用[appDel saveManagedObjectContext]
,在第二种方法中,您使用[appDel managedObjectContext]
。看起来这些应该是相同的上下文,以便您进行提取。是吗
更新:
正如您在评论中所述,这可以解决保存问题,但是现在您遇到了性能问题–将用户界面保存到磁盘块上的持久性存储中,这就是您的原始代码试图解决的问题。
这是一个已解决的问题。解决方案是,与用户连接的主线程上下文应该是与持久性存储接口的后台线程上下文的子级。此2015 blog post by Marcus Zarra中的代码对此进行了很好的解释。要进一步阅读,请Chad Wilken has published a slight variation。两者都是用Objective-C为您编写的:)