Я вставляю свои CoreData в фоновый контекст, и при получении, он не показывает данные - PullRequest
1 голос
/ 09 апреля 2019

Я пытаюсь выполнить операцию с основными данными в фоновом контексте. Я вставляю все свои данные в фоновый контекст, но когда я получаю данные в основном потоке, он не показывает никаких данных, которые я уже вставил. Я не знаю, где я делаю ошибку ... :( Любую помощь оцените.

Это то, что я пробовал для вставки, а второй для извлечения данных.

- (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"];
}


1 Ответ

0 голосов
/ 09 апреля 2019

Ошибка, которую вы делаете, заключается в том, что вы не протестировали множество маленьких кусочков этого кода, которые могли работать не так, как ожидалось. Чтобы устранить неполадки, подобные этим, вы должны начать с начала и тестировать по одной части за раз. Первая проблема, которую я вижу, - это путаница между контекстами управляемого объекта…

  • Похоже, что метод saveManagedObjectContext является геттером для вашего основного контекста управляемого объекта. В английском языке save является глаголом, так что это имя метода подразумевает, что оно сохраняет некоторый контекст управляемого объекта. Если я прав, вы должны изменить имя saveManagedObjectContext на mainMangaedObjectContext.

  • Оператор _managedObjectContext = [appDel managedObjectContext] является довольно нестандартным, присваивая переменной экземпляра то, что представляется ее получателем. Если, как обычно, _managedObjectContext является переменной экземпляра, поддерживающей свойство managedObjectContext, этот оператор не действует.

  • В вашем первом методе вы используете [appDel saveManagedObjectContext], а во втором - [appDel managedObjectContext]. Похоже, что они должны быть в том же контексте, чтобы ваш выбор работал. Они?

UPDATE:

Как вы указали в своем комментарии, это исправляет сохранение, но теперь у вас есть проблема с производительностью - сохранение в постоянном хранилище на диске блокирует пользовательский интерфейс, что и пытался исправить ваш оригинальный код.

Это решенная проблема. Решение состоит в том, что ваш контекст основного потока, который взаимодействует с пользователем, должен быть потомком вашего контекста фонового потока, который взаимодействует с постоянным хранилищем. Это хорошо объясняется с помощью кода в этом посте 2015 от Marcus Zarra . Для дальнейшего чтения Чед Уилкен опубликовал небольшое изменение . Оба написаны в Objective-C для вас:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...