2010-08-29 4 views
9

В моем представлении таблицы отображается список пользователей. У меня возникают проблемы с обновлением моего представления таблицы после добавления пользователя. Я пробовал разные комбинации кода и событий, и теперь приложение терпит крах при вызове endUpdates. Приложение смоделировано после приложения рецепта, поэтому пользователь нажимает кнопку добавления, а затем появляется модальное окно с запросом имени пользователя. Затем он переходит на экран редактирования, а затем возвращается к списку пользователей. В этот момент новый пользователь не появлялся. Но если я вернусь на главный экран, а затем вернусь к экрану пользователей, появится пользователь.iPhone app crashing on [self.tableView endUpdates]

Вот некоторые из моего кода:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
    sectionInsertCount = 0; 
    [self.tableView beginUpdates]; 
} 
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView endUpdates]; 

} 

    - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { 
switch(type) { 

    case NSFetchedResultsChangeInsert: 
      if (!((sectionIndex == 0) && ([self.tableView numberOfSections] == 1))) { 
       [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
       sectionInsertCount++; 
      } 

    break; 
    case NSFetchedResultsChangeDelete: 
      if (!((sectionIndex == 0) && ([self.tableView numberOfSections] == 1))) { 
       [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
       sectionInsertCount--; 
      } 

    break; 
     case NSFetchedResultsChangeMove: 
      break; 
     case NSFetchedResultsChangeUpdate: 
      break; 
     default: 
      break; 
} 
} 

    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { 
switch(type) { 
    case NSFetchedResultsChangeInsert: 
      [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
    break; 
    case NSFetchedResultsChangeDelete: 
    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
    break; 
     case NSFetchedResultsChangeUpdate: { 
      [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     } 
    case NSFetchedResultsChangeMove: 
      if (newIndexPath != nil) { 

       NSUInteger tableSectionCount = [self.tableView numberOfSections]; 
       NSUInteger frcSectionCount = [[controller sections] count]; 
       if (frcSectionCount != tableSectionCount + sectionInsertCount) { 
        [self.tableView insertSections:[NSIndexSet indexSetWithIndex:[newIndexPath section]] withRowAnimation:UITableViewRowAnimationNone]; 
        sectionInsertCount++; 
       } 


       [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
       [self.tableView insertRowsAtIndexPaths: [NSArray arrayWithObject:newIndexPath] 
            withRowAnimation: UITableViewRowAnimationRight]; 

    runEndUpdates = NO; 

      } 
      else { 
       [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[indexPath section]] withRowAnimation:UITableViewRowAnimationFade]; 
      } 
    break; 
     default: 
    break; 
} 
} 

Я почти в точке разрыва с этим. CoreData была самой расстраивающей частью разработки приложений. Должен ли я просто переключиться на SQL Lite? Или у меня остались те же проблемы?

Спасибо!

ответ

2

Сегодня у меня была такая же проблема.

Проблема была в моем исходном коде - одна из функций UITableViewDataSource использовала недопустимый объект (не объект CoreData, простой массив, который я забыл сохранить), это вызвало сбой. К сожалению, это не было ясно из стека вызовов, в консоли не было сообщений.

Таким образом, причина может заключаться в реализации протокола UITableViewDataSource.

+0

Но если вы используете fetchedResultsController (как это сделал автор), здесь очень сложно совершить ошибку :) Количество разделов: return [self.fetchedResultsController.sections count]; Число строкInSection: return [self.fetchedResultsController.sections [section] numberOfObjects]; – Miroslav

-3

Попробуйте позвонить [self.tableview reloaddata] внутри контроллераDidChangeContent.

+6

, который убивает всю цель оживления изменений строк. – samvermette

+0

«Вы не должны вызывать reloadData внутри группы, если вы вызываете этот метод внутри группы, вам нужно будет выполнить любую анимацию самостоятельно». - из документации Apple: https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/beginUpdates – Fabio

5

По моему опыту, он должен содержать несколько строк или разделов, вставленных или удаленных между beginUpdated и endUpdated. Если никакие строки или секции не вставлены или не удалены между beginUpdated и endUpdated, это приведет к сбою.

И, если номер раздела и номер строки неверны, он также потерпит крах. Таким образом, он нуждается в кодировании очень тщательно.

+0

Это исправило проблему I имел. Я фильтровал строки с помощью UISearchBar и NSFetchedResultsController. Пользователь будет выбирать строку, запускающую событие сохранения в файле didSelectRowAtIndexPath. Создав флаг и установив NO, остановил UITableView beginUpdates и endUpdates, которые вызываются и решают проблему. Спасибо Toro – RobCroll

2

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

В моем представлении таблицы есть куча событий, отсортированных по дате. События запрашиваются из веб-API 50 за раз. Каждый раз, когда выполняется новый запрос, появляется обновленное обновление результатов и новые ячейки. В начале я заметил много странного смещения, когда новые строки будут добавлены, но просто казалось, что нужно оптимизировать позже.

События в приложении могут быть сохранены, а в режиме таблицы есть способ фильтрации между всеми событиями и сохраненными событиями. Однажды я просто нажал на фильтр, чтобы переключаться между всеми событиями и сохраненными событиями, и я заметил, что в тот конкретный день, когда я переключился на представление всех событий, они были бы перегруппированы.

О, да, мне также нужен дескриптор для времени начала. Это то, что сделает приложение более приятным в использовании.

OH DUH! Держу пари, вот почему он тоже рушится! Поскольку каждое обновление в основном заставляло каждую существующую строку перемещаться в новое место, а также добавляло дополнительные строки, я, должно быть, просто ударил ошибку при сбое в контроллере табличного представления. Теперь проблемы с прокруткой исчезли, и авария тоже исчезла.

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