0

NSFetchRequestmy に渡す を作成するときNSFetchedResultsControllerは、fetchLimit プロパティを 3 に設定しています。

これで、最初は問題なく動作するように見えます。返された最初の 3 つのオブジェクトを任意の方法で変更して順序を変更でき、それらはすべて正しく再シャッフルされます。この問題は、最初は最初の 3 つに入らなかったオブジェクトを変更して最初の 3 つにするか、単に新しいオブジェクトを追加して最初の 3 つに収まるようにするときに発生します。

私が予想したこと: 挿入されたオブジェクトが残りを押し下げ、1 つが底から落ちます。

実際に何が起こるか: 挿入されたオブジェクトが残りを押し下げ、レコード数が 4 に増える?!

誰かがこれを説明できますか、またはこれにどのように対処すればよいですか?

4

1 に答える 1

7

numberOfObjects基本的に、テーブルを固定したい実際の長さを無視して返すことで、これを回避する作業を進めました。これには少しコツが必要controller:didChangeObject:...ですが、これまでのところうまくいっているようです。

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

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
    UITableView *tableView = self.myTableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:

            // Only modify table if insert will effect visible rows
            if (newIndexPath.row < kTableSize) {
                // Delete last row to maintain fixed length
                [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:(kTableSize - 1) inSection:newIndexPath.section]] withRowAnimation:UITableViewRowAnimationAutomatic];

                [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            }
            break;

        case NSFetchedResultsChangeDelete:

            // Only modify table if delete will effect visible rows
            if (indexPath.row < kTableSize) {
                [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

                // Insert extra row to maintain fixed length
                [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:(kTableSize - 1) inSection:newIndexPath.section]] withRowAnimation:UITableViewRowAnimationAutomatic];
            }
            break;

        case NSFetchedResultsChangeUpdate:

            // Only modify table if update will effect visible rows
            if (indexPath.row < kTableSize) {
                [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            }
            break;

        case NSFetchedResultsChangeMove:

            // Only modify table if move will effect visible rows
            if ((indexPath.row < kTableSize) || (newIndexPath.row < kTableSize)) {


                // Delete old row or last row of table
                if (indexPath.row < kTableSize) {
                    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
                } else {
                    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:(kTableSize - 1) inSection:newIndexPath.section]] withRowAnimation:UITableViewRowAnimationAutomatic];
                }

                // Insert new row or a row at bottom of table
                if (newIndexPath.row < kTableSize) {
                    [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
                } else {
                    [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:(kTableSize - 1) inSection:newIndexPath.section]] withRowAnimation:UITableViewRowAnimationAutomatic];
                }
            }
            break;
    }
}

またtableView:cellForRowAtIndexPath:、テーブルの長さよりもオブジェクトが少ない場合に、存在しないオブジェクトにアクセスしようとしないように注意する必要があります。

于 2012-05-17T16:07:12.260 に答える