NSFetchedResultsController аварийно завершает работу на objectAtIndexPath?
Я получаю сбой при попытке получить доступ к объекту в NSFetchedResultsController
,
2013-11-10 15:15:06.568 Social[11503:70b] CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. *** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds for empty array with userInfo (null)
2013-11-10 15:15:06.570 Social[11503:70b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds for empty array'
viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
self.resultController = [DataEngine sharedInstance].postsFetchedResultController;
self.resultController.delegate = self;
[self.resultController performFetch:nil];
[self.tableView reloadData];
[[DataEngine sharedInstance] fetchInBackground];
}
Делегат контроллера результатов
#pragma mark - NSFetchedResultsControllerDelegate Methods -
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
switch (type)
{
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeMove:
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
break;
default:
break;
}
}
вид таблицы
#pragma mark - UITableView Delegate & Datasrouce -
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.resultController.fetchedObjects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [self cellForRowAtIndexPath:indexPath];
}
2 ответа
В одном из моих подклассов NSManagedObject у меня был следующий код, который вызывал проблему. NSSets автоматически инициализируются в NSManagedObejcts, и нет необходимости их инициализировать.
- (void)awakeFromFetch
{
if (!self.comments)
self.comments = [NSMutableSet set];
if (!self.medias)
self.medias = [NSMutableSet set];
}
Другая проблема заключалась в том, что во время вставки indexPath имеет значение null, вместо этого мне пришлось использовать newIndexPath
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:@[newIndexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
break;
Одной из причин сбоя в строке ниже может быть то, что вы обновляете self.resultContrlller после того, как использовали его для перенастройки количества строк в разделе таблицы. Убедитесь, что если вы постоянно обновляете свой объект self.resultContrlller, вы берете его копию и затем используете для рисования таблицы.
// This code does not prevent crash. Changing your regular code to modern objective-C way
Post *post = [self.resultContrlller fetchedObjects][indexPath.row];
Источник данных не должен изменяться во время перезагрузки таблицы. Вместо этого вы должны использовать копию fetchedObjects для загрузки таблицы. Итак, перед тем как перезагрузить таблицу, возьмите копию [[self.resultContrlller fetchedObjects] copy] и используйте ее для рисования таблицы. Ваш основной источник может продолжать меняться. И после перезагрузки таблицы с копией вы можете захотеть перезагрузить ее снова, если произошли изменения в данных. Такие сбои происходят, когда ваш источник данных изменяется быстрее, чем перезагружается таблица.