3

UICollectionViewでperformBatchUpdates:completion、グリッドビューの更新を実行するために使用しようとしています。私のデータソース配列はself.resultsです。

これが私のコードです:

dispatch_sync(dispatch_get_main_queue(), ^{

            [self.collectionView performBatchUpdates:^{

                int resultsSize = [self.results count];
                [self.results addObjectsFromArray:newData];

                NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];
                if (resultsSize == 0) {
                    [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:0 inSection:0]];
                }

                else {
                    for (int i = 0; i < resultsSize; i++) {
                        [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:resultsSize + i inSection:0]];
                    }
                }

                for (id obj in self.results)
                    [self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths];

            } completion:nil];

私が持っているもの/私がしていることの説明:

このコードは、コレクションビューへの最初の挿入が完了すると正常に実行されます。ただし、コレクションビューにデータを追加/挿入すると(self.resultsこれを更新して呼び出すことにより)、次のエラーが発生します。

*キャッチされなかった例外によるアプリの終了'NSInternalInconsistencyException'、理由:'無効な更新:セクション0のアイテムの数が無効です。更新後の既存のセクションに含まれるアイテムの数(8)は、に含まれるアイテムの数と同じである必要があります更新前のそのセクション(4)、プラスまたはマイナスそのセクションから挿入または削除されたアイテムの数(32挿入、0削除)およびプラスまたはマイナスそのセクションに移動または移動されたアイテムの数(0移動、0引っ越した)。'

これは、データソースが適切に更新されなかったことを意味することを理解しています。ただし、self.results配列をクエリすると、データの新しいカウントが表示されます。を使用して最初の行でそれを行っていaddObjectsFromArrayます。古い結果のサイズもに保存しましたresultsSize。その変数を使用して、新しく追加されたインデックスパスをに追加しますarrayWithIndexPaths

アイテムを追加/挿入するときに、次のforループを試しました。

for (id obj in self.results)これが私が今使っているものです。最初は機能しますが、さらにクラッシュが挿入されます。

for (UIImage *image in newData)最初は同様に機能しますが、さらにインサートがクラッシュします。

関数の名前から、insertItemsAtIndexPathsループなしでそれらのインデックスパスにすべてのアイテムを挿入すると思います。ただし、ループがないと、アプリは最初にデータを入力しようとしたときにクラッシュします。

resultsSize + 1また、新しいカウント(新しいデータを含む)までループしようとしself.resultsましたが、これも最初の更新時にクラッシュします。

私が間違っていることについて何か提案はありますか?

ありがとうございました、

4

1 に答える 1

14

ここでいくつか間違っていることがわかります。まず、dispatch_syncを使用している理由がわかりません。また、GCDの経験があまりなく、GCDを使用することができませんでした(ハングしているようで、UIが応答しませんでした)。おそらく他の誰かがそれを手伝ってくれるでしょう。次に、インデックスパスを追加するループでは、resultsSizeをループしています。これは、私が理解しているように、更新前の配列のサイズであり、必要なサイズではありません。新しいインデックスを次の場所で開始します。 resultsSizeを実行し、resultsSize+newData.countまでループします。最後に、insertItemsAtIndexPathsを呼び出すときは、ループではなく、一度だけ実行する必要があります。私はこれを試しましたが、コレクションビューを更新するために機能しました(空のコレクションビューで最初から試したわけではありません)。

-(void)addNewCells {
    [self.collectionView performBatchUpdates:^{
        int resultsSize = [self.results count];
        [self.results addObjectsFromArray:newData];
        NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];
        for (int i = resultsSize; i < resultsSize + newData.count; i++) {
            [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
        }
            [self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths];
    }
        completion:nil];
}
于 2012-09-30T23:33:15.783 に答える