我在后台 Context 中插入我的 CoreData,当我获取时,它不显示数据

I insert my CoreData in background Context and when I fetch, it doesn't show the 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"];
}


您犯的错误是没有测试此代码的许多小片段,它们可能无法按预期工作。要解决此类问题,您必须从头开始,一次测试一件。我看到的第一个问题是托管对象上下文之间的混淆......

  • 方法 saveManagedObjectContext 似乎是您的主要托管对象上下文的 getter。在英语中,save 是一个动词,因此这个方法名称暗示它正在保存一些托管对象上下文。如果我是正确的,您应该将名称 saveManagedObjectContext 更改为 mainMangaedObjectContext.

  • 语句 _managedObjectContext = [appDel managedObjectContext] 非常不标准,它从看似 getter 的内容分配给实例变量。如果像往常一样,_managedObjectContext 是支持 属性 managedObjectContext 的实例变量,则此语句无效。

  • 第一种方法使用[appDel saveManagedObjectContext],第二种方法使用[appDel managedObjectContext]。看起来这些应该是相同的上下文才能使您的提取工作。他们是吗?

更新:

正如您在评论中所述,这修复了保存问题,但现在您遇到了性能问题 – 保存到磁盘上的持久存储会阻塞用户界面,这正是您的原始代码试图修复的问题。

这是一个已解决的问题。解决方案是,与用户交互的主线程上下文应该是与持久存储交互的后台线程上下文的子项。 2015 blog post by Marcus Zarra. For further reading, Chad Wilken has published a slight variation 中的代码对此进行了很好的解释。都写在 Objective-C 给你:)