iPhone: NSFetchedResultsController с делегатом и данными обновляют от отдельного потока

В первую очередь, жаль о слишком длинном вопросе.

Я знаю, что существует немного вопросов здесь, которые обсуждают подобные вопросы, но ни одни из этих переговоров о NSFetchedResultsController с делегатом вместе с обновлением в отдельном потоке. И ни одно из решений не помогло мне.
Это существующие вопросы:

Теперь о моей проблеме:

  • У меня есть отдельный поток, который обновляет базовые объекты данных от сети (использование сокета).
  • Существует немного контроллеров представления, которые отображают данные из того же базового объекта данных (каждая вкладка содержит контроллер представления, который отображает его фильтрованные данные).
  • Каждый контроллер представления имеет свой собственный экземпляр NSFetchedResultsController и делегат установлен на сам.

Иногда я получаю was mutated while being enumerated исключение при обновлении данных в отдельном потоке и иногда это разрушает приложение.

Я сделал много манипуляций кодом, чтобы попытаться зафиксировать его и кажусь, что ничто не помогает.
Я попытался не использовать управляемый объект непосредственно из методов источника данных табличного представления. Вместо этого я создал массив, который содержит список словарей. я заполняю те словари didChangeObject метод сверху. Таким образом, я не касаюсь управляемых объектов вообще в контроллере представления.

И затем я понял, что проблема находится в NSFetchedResultsController, который, вероятно, выполняет итерации данных все время. И это - объект, который конфликтует с моим обновлением данных в отдельном потоке.

Вопрос состоит в том, как я могу обновить базовые объекты данных в отдельном потоке, после того как у меня есть NSFetchedResultsController с делегатом (подразумевать, что он "наблюдает" данные и обновляет делегата все время).

Реализация NSFetchedResultsControllerDelegate:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
    if ( self.tabBarController.selectedIndex == 0 ) {
        UITableView *tableView = self.tableView;
        @try {
            switch(type) 
            {
                case NSFetchedResultsChangeInsert:
                    [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                    break;
                case NSFetchedResultsChangeDelete:
                    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                    break;
                case NSFetchedResultsChangeUpdate:
                    [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
                    break;
                case NSFetchedResultsChangeMove:
                    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                    [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
                    break;
            }
        }
        @catch (NSException * e) {
            NSLog(@"Exception in didChangeObject: %@", e);
        }
    }
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
    if ( self.tabBarController.selectedIndex == 0 ) {
        @try {
            switch(type) {
                case NSFetchedResultsChangeInsert:
                    [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                    break;
                case NSFetchedResultsChangeDelete:
                    [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                    break;
            }           
        }
        @catch (NSException * e) {
            NSLog(@"Exception in didChangeSection: %@", e);
        }
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{
    [self.tableView endUpdates];
}

В методах источника данных табличного представления я работаю непосредственно с управляемым объектом.

5
задан Community 23 May 2017 в 12:15
поделиться

0 ответов

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

Похожие вопросы: