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) であるため、セクションの問題ではないことがわかります。理論的には、これら 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]);
    }
}

ここで何か間違ったことをしていますか?

4

4 に答える 4

17

私は同じ問題に遭遇しました。私の場合、破損したキャッシュ ファイルのようです。キャッシュの名前を変更するか、 を呼び出してみてくださいdeleteCacheWithName:

于 2012-08-10T17:17:16.123 に答える
6

フェッチ リクエスト コントローラを初期化したときにsectionNameKeyPath:、データにセクションがなくても を指定しました。次に、テーブルのセクション番号を 1 にハードコーディングしました。

フェッチ要求コントローラーは、セクションをまったく持たないデータ構造のセクション インデックス 0 でオブジェクトを返そうとしています。

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 がどこを指していたのかがわかります。ないかもしれないときに、1 つのセクションがあることをテーブル ビューに伝えています。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 つの長引くエラーがあるようです。

于 2010-07-03T14:09:01.270 に答える