Я вставляю свои CoreData в фоновый контекст, и когда я извлекаю, он не показывает данные

Я пытаюсь выполнить операцию 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"];
}


Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
113
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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

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

ОБНОВИТЬ:

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

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

Спасибо @Jerry Krinock, в запросе на выборку (второй метод), если я изменю _managedObjectContext = [appDel manageObjectContext]; в NSManagedObjectContext *saveObjectContext = [appDel saveManagedObjectContext]; оно работает. и если я изменю оба метода на основной mainMangaedObjectContext, он сработает.. но моя проблема в том, что мне нужно сохранить много данных из JSON в основных данных во время его сохранения, основной вид приложения начинает блокироваться до тех пор, пока он не завершит свою работу, что я Я пытаюсь сделать всю эту операцию в фоновом потоке, чтобы не блокировать основной поток....

Steven 10.04.2019 10:14

это метод сохранения контекста объекта управления - (NSManagedObjectContext *) saveManagedObjectContext { if (writerManagedObjectContext! = nil) { returnwriterManagedObjectContext; } NSPersistentStoreCoordinator *coordinator = [самостоятельный постоянныйStoreCoordinator]; if (координатор != nil) {writerManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [writerManagedObjectContext setPersistentStoreCoordinator:координатор]; } вернуть writeManagedObjectContext; }

Steven 10.04.2019 10:14

В Swift, если я хочу сохранить их все в фоновом контексте, я могу сделать что-то вроде этого: let backgroundContext:NSManagedObjectContext!backgroundContext = persistentContainer.newBackgroundContext() но в target -c кажется, что метод newBackgroundContext() не существует.

Steven 10.04.2019 10:25

Смотрите ОБНОВЛЕНИЕ: в моем ответе выше.

Jerry Krinock 10.04.2019 16:47

Другие вопросы по теме