NSFetchedResultsController - методы делегирования, сбойные под iPhone OS 3.0, но НЕ ПОД 3.1 - PullRequest
0 голосов
/ 01 апреля 2010

Привет, ребята, так что мой NSFetchedResultsController работает нормально под 3.1 SDK, однако я начинаю получать некоторые странные ошибки, особенно в методах делегатов, когда я пытаюсь под 3.0. Я определил, что это связано с методами NSFetchedResultsControllerDelegate. Это то, что я настроил.

Материал inEditingMode связан с тем, как я реализовал добавление еще одного статического раздела в таблицу.

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


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type{
    NSIndexSet *sectionSet = [NSIndexSet indexSetWithIndex:sectionIndex];

    if(self.inEditingMode){
        sectionSet = [NSIndexSet indexSetWithIndex:sectionIndex + 1];
    }

    switch (type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:sectionSet withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:sectionSet withRowAnimation:UITableViewRowAnimationFade];
            break;
        default:
            [self.tableView reloadData];
            break;

    }
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath{
    NSIndexPath *relativeIndexPath = indexPath;
    NSIndexPath *relativeNewIndexPath = newIndexPath;

    if(self.inEditingMode){
        relativeIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section + 1];
        relativeNewIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:newIndexPath.section + 1];
    }

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:relativeNewIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:relativeIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        default:
            [self.tableView reloadData];
            break;
    }
}


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

Когда я добавляю объект в контекст управляемого объекта, я получаю следующую ошибку:

Serious application error.  Exception was caught during Core Data change processing: *** -[NSCFArray objectAtIndex:]: index (1) beyond bounds (1) with userInfo (null)

Я поставил точку останова на objc_exception_throw, и, похоже, происходит сбой внутри controllerDidChangeContent.

Если я закомментирую все методы self.tableView и поместу один [self.tableView reloadData] в controllerDidChangeContent, все будет работать как положено.

Кто-нибудь имеет представление о том, почему это происходит?

1 Ответ

2 голосов
/ 01 апреля 2010

В документации для NSFetchedResultsController есть конкретное упоминание об ошибке в реализации 3.0, которая приводит к расхождению между числом секций, сообщаемых контроллером, и количеством секций, ожидаемых UITableView. Это обходной путь, который они предоставляют:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    NSUInteger count = [[<#Fetched results controller#> sections] count];
    if (count == 0) {
        count = 1;
    }
    return count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    NSArray *sections = [<#Fetched results controller#> sections];
    NSUInteger count = 0;
    if ([sections count]) {
        id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:section];
        count = [sectionInfo numberOfObjects];
    }
    return count;
}

Обратите внимание, что этот обходной путь не требуется для ОС 3.1, поэтому это может объяснить, почему вы не видите ошибок. Обходной путь необходим только в версии 3.0, когда для sectionNameKeyPath установлено значение nil. Если вы устанавливаете значение для sectionNameKeyPath, то это, вероятно, не проблема.

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