テーブルビューに項目を表示するために 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) であるため、セクションの問題ではないことがわかります。理論的には、これら 2 つのコードは同じことを行うため、なぜこれが起こっているのかについて非常に混乱しています。どんな助けでも大歓迎です。
ありがとう
更新:
id section = [[[self fetchedResultsController] sections] objectAtIndex:[indexPath section]];
NSLog(@"Section %@", section); <-- returns a valid section
このコードでは、同じ例外が発生します。Tag *tag = [[section objects] objectAtIndex:[indexPath row];
I の場合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]);
}
}
ここで何か間違ったことをしていますか?