Основные данные Выполнение выборки в PerformBlock в фоновом потоке

Когда я пытаюсь выполнить выборку в фоновом контексте, он говорит: [NSManagedObjectContext Multithreading_Violation_AllThatIsLeftToUsIsHonor] ()

В фоновом потоке я хочу проверить, существует ли объект, а затем обновить. Если это не так, я вставляю его, а затем обновляю. По какой-то причине xcode продолжает говорить, что у меня есть нарушение параллелизма, когда я пытаюсь выполнить выборку. Мне не разрешено выполнять выборку в фоновом контексте?

Это моя настройка для моих контекстов:

Persistent store -> Root saving context -> default context (concurrency type main) persistent store -> Root saving context -> background context (concurrency type private)

фоновый контекст пытается выполнить блокировку:

    NSManagedObjectContext *backgroundContext = [NSManagedObjectContext MR_context];
    [backgroundContext performBlock:^{
        [Conversation parseConversationAndCalls:objects inContext:backgroundContext];

        ...
    }];

то вызов метода parseConversationAndCalls выполнит выборку:

+ (void) parseConversationAndCalls:(NSArray*)objects inContext:(NSManagedObjectContext*)localContext {
    ...
    for (NSArray *callData in conversationsCallData) {

        NSNumber *callID = [BPDObject scrubbedInteger:callData[1]];
        Call *call = (Call*) [FetchRequestHelper fetchWithClass:Call.self withID:callID inContext:localContext];  // breakpoint hit here

        if (call == nil) {
            call = [Call insertInManagedObjectContext:localContext];
        }

        [call updateWithValues:callData inContext:localContext];
        call.contact = contact;
    }
}

помощник fetchrequest просто создает запрос на выборку, FRC, затем выполняет выборку в блоке PerformBlock:

    ... //here context is the same as backgroundContext and frc is the fetched results controller
    context.performAndWait {
        do {
            try frc.performFetch()
        } catch {
            fatalError("Failed to perform fetch from FetchedResultsController: \(error)")
        }
    }

Любая помощь будет оценена


person Minimi    schedule 30.05.2017    source источник


Ответы (1)


Обычно fetchedResultsController запускается в основном потоке, потому что он используется для обновления пользовательского интерфейса. Когда был создан fetchedResultsController, ему был предоставлен управляемый контекст объекта, который, как я сильно подозреваю, был основным контекстом. Поэтому, когда вы вызываете try frc.performFetch() в фоновом контексте, вы получаете доступ к контексту основного потока в фоновом потоке.

Это то, что я смог увидеть в коде, которым вы поделились. Могут быть и другие нарушения, о которых вы не сообщили. Удачи в их отслеживании.

person Jon Rose    schedule 01.06.2017
comment
Возможно ты прав. В итоге я использовал запрос на выборку без FRC, и это сработало нормально. - person Minimi; 07.06.2017