NSFetchedResultsController индексируют вне границ

Я использую NSFetchedResultsController для экспонатов в моем табличном представлении:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [[self.fetchedResultsController fetchedObjects] count];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"TagCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];;
    }

 Tag *tag = [self.fetchedResultsController objectAtIndexPath:indexPath];
 cell.textLabel.text = tag.name;

    return cell;
}

Однако этот код повреждается в этой строке:

Tag *tag = [self.fetchedResultsController objectAtIndexPath:indexPath];

С этим сообщением:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'

У меня есть NSLogged [self.fetchedResultsController fetchedObjects] и я могу подтвердить, что существуют действительно объекты Тега. Если я заменяю это выше строки с этим, все работает как ожидалось:

Tag *tag = [[self.fetchedResultsController fetchedObjects] objectAtIndex:indexPath.row];

Я NSLogged indexPath и индексы {0, 0} (разделите 0 строк 0), таким образом, я знаю, что это не проблема с разделом. Я чрезвычайно смущен относительно того, почему это происходит, потому что теоретически, те две части кода делают то же самое. Любая справка ценится.

Спасибо

ОБНОВЛЕНИЯ:

id section = [[[self fetchedResultsController] sections] objectAtIndex:[indexPath section]];
NSLog(@"Section %@", section); <-- returns a valid section

Этот код приводит к тому же исключению: Tag *tag = [[section objects] objectAtIndex:[indexPath row];

Если я NSLog [section objects] это возвращает пустой массив. Я не уверен почему [fetchedResultsController fetchedObjects] возвращает массив с правильными объектами, и [section objects] возвраты ничто. Это означает, что объекты, которые я создаю, не имеют никакого раздела? Вот код, который я использую для добавления новых объектов:

- (void)newTagWithName:(NSString *)name
{
    NSIndexPath *currentSelection = [self.tableView indexPathForSelectedRow];
    if (currentSelection != nil) {
        [self.tableView deselectRowAtIndexPath:currentSelection animated:NO];
    }    

    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
    Tag *newTag = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:self.managedObjectContext];

    // Configure new tag

    newTag.name = name;

    [self saveContext];

    NSIndexPath *rowPath = [self.fetchedResultsController indexPathForObject:newTag];
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:rowPath] withRowAnimation:UITableViewRowAnimationTop];
    [self.tableView selectRowAtIndexPath:rowPath animated:YES scrollPosition:UITableViewScrollPositionTop];
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}

И вот мой saveContext метод:

- (void)saveContext
{
    // Save changes

    NSError *error;
    BOOL success = [self.managedObjectContext save:&error];
    if (!success)
    {
        UIAlertView *errorAlert = [[[UIAlertView alloc] initWithTitle:@"Error encountered while saving." message:nil delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil] autorelease];
        [errorAlert show];
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    }
}

Я делаю что-то не так здесь?

6
задан indragie 3 July 2010 в 16:50
поделиться

2 ответа

Когда вы инициализировали контроллер запроса на выборку, вы дали ему sectionNameKeyPath: , даже если ваши данные не имеют разделов. Затем вы жестко задали номер раздела таблиц равным 1.

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

Я воспроизвел вашу ошибку в приложении шаблона навигации по умолчанию, изменив sectionNameKeyPath с nil на имя единственного атрибута объекта.

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"timeStamp" cacheName:@"Root"];

... а затем изменил

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//    return [[fetchedResultsController sections] count];
     return 1;
}

, и я получаю:

 *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'

Установите sectionNameKeyPath: nil , и это должно решить вашу проблему.

6
ответ дан 8 December 2019 в 04:28
поделиться

Вы компилируете, нацеливаете или тестируете на 3.0?

Что вы получаете от следующего кода:

id section = [[[self fetchedResultsController] sections] objectAtIndex:[indexPath section]];
NSLog(@"Section %@", section);

Вы получаете правильную секцию обратно?

Если да, попробуйте добавить следующую строку:

Tag *tag = [[section objects] objectAtIndex:[indexPath row];

Если это приводит к ошибке, я подозреваю, что проблема в вашем -tableView: numberOfRowsInSection: и что это может возвращать неправильное количество строк в UITableView. Не могли бы вы отредактировать свой вопрос и выложить код этого метода?

Обновление

При дальнейшем рассмотрении я понял, на что указывал TechZen. Вы сообщаете табличному представлению, что у вас есть одна секция, хотя это может быть не так. Далее, вы говорите ему, сколько объектов имеет весь ваш NSFetchedResultsController, тогда как вам следовало бы ответить на этот вопрос немного более кратко.

Вот небольшое изменение в вашем коде.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{
  return [[self fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
  return [[[self fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}

Внесите эти изменения и посмотрите, какое влияние это окажет.

Вопрос

Какие еще методы UITableViewDataSource вы реализовали? Похоже, что в вашей реализации может быть как минимум еще одна ошибка.

1
ответ дан 8 December 2019 в 04:28
поделиться
Другие вопросы по тегам:

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