0

私はiOS開発に不慣れであり、これは私がここにたくさん来るにもかかわらず、stackoverflowに関する私の最初の質問です。このような素晴らしいリソースをありがとう!

スタンフォードCS193Pコースを受講していて、「割り当て5追加クレジット1」で問題が発生しています。
タイトル、サブタイトル、サムネイルを表示するUITableViewがあります。サムネイルフェッチをキューに入れましたが、サムネイル画像が戻ってきたときにテーブルセルがリサイクルされていないことを確認する必要があります。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Photo";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    NSDictionary *imageDescription = [self.photoList objectAtIndex:indexPath.row];
    NSString *expectedPhotoID = [imageDescription objectForKey:FLICKR_PHOTO_ID];

    // Configure the cell...

    cell.imageView.image = [UIImage imageNamed:@"placeholder.png"];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        UIImage *imageThumb = [self imageForCell:imageDescription];
        [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]]; // simulate 2 sec latency

        dispatch_async(dispatch_get_main_queue(), ^{
            NSString *photoID = [imageDescription objectForKey:FLICKR_PHOTO_ID];
            if ([expectedPhotoID isEqualToString:photoID]) {
                cell.imageView.image = imageThumb;
            } else {
                NSLog(@"cellForRowAtIndexPath: Got image for recycled cell");
            }
        });
    });

  return cell;
}

このコードでは、photoID常にに一致しexpectedPhotoIDます。imageDescriptionこれは、作成時に両方のキューにポインターが使用されているためだと思います。[self.photoList objectAtIndex:indexPath.row](の代わりに)直接使用してみましimageDescriptionたが、どちらも機能しませんでした。キューが作成された時点でも解決されているようです。

私はここでいくつかの基本的な理解を欠いています、そしてあなたの助けに感謝します。

4

1 に答える 1

1

テーブルビューは、すべての行にテーブルビューセルを割り当てるわけではありません。代わりに、表示されている行(またはもう少し)のセルのみが割り当てられます。表をスクロールすると、一部の行が消え、他の行が表示されます。新しく表示された行の場合、テーブルビューは不要になったセルを再利用しようとします。(それが何をするかdequeueReusableCellWithIdentifier:です。)

非同期タスクを開始してセルの画像を取得すると、次のことが発生する可能性があります。

タスクが終了し、最も内側のブロックが実行されると、その間にセルは別の行で再利用されます。その場合、画像をセルに割り当てることは意味がありません。

したがって、画像を作成するときは、セルが以前と同じ位置にあることを確認する必要があります。たとえば、値を呼び出し[tableView indexPathForCell:cell]て元の値と比較できindexPathます。それらが同一である場合、セルは同じ位置にあり、画像を割り当てることができます。そうでない場合は、画像を破棄する必要があります。

しかし、それは最も単純な解決策にすぎません。より良い解決策は、すべての行の画像をキャッシュすることです。

WWDC2012セッション2011「iOSでの同時ユーザーインターフェイスの構築」のみをお勧めします。このトピックをカバーしています。

于 2012-08-14T18:04:48.110 に答える