6

我正在使用 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 *tag = [[self.fetchedResultsController fetchedObjects] objectAtIndex:indexPath.row];

我 NSLoggedindexPath并且索引是 {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]);
    }
}

我在这里做错了吗?

4

4 回答 4

17

我遇到了同样的问题。就我而言,它似乎是一个损坏的缓存文件。尝试重命名缓存,或调用deleteCacheWithName:.

于 2012-08-10T17:17:16.123 回答
6

当你初始化你的获取请求控制器时,你给了它一个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并且应该可以解决您的问题。

于 2010-07-03T18:32:06.163 回答
1

昨晚得到了这个错误,它让我发疯了。我发现如果您使用情节提要来指定行数和节数,它需要与您在数据源方法中指定的数字相匹配。要完全修复错误,您可以在属性检查器中将所有内容设置为 0,然后以编程方式完成所有操作,或者只是确保数据源方法和属性检查器反映相同数量的行和部分。

^^

于 2012-11-18T23:08:35.863 回答
1

您是否针对 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方法?听起来您的实现中可能至少还有一个挥之不去的错误。

于 2010-07-03T14:09:01.270 回答