1

私はカスタムテーブルセルを描画してきました(Appleのサンプルをベースとして使用)が、URLから画像を表示するセルを作成する必要が生じました-各セルには異なる画像があります(あるデータに基づいて) )しかし、すべてのセルは同じであるため、同じ再利用IDです。

これを行うための正しい構造は何ですか? 明らかに、新しいスレッドに画像をロードする必要があります。これまでのところ、独自のスレッドで実行されるセルビュークラスに次の関数があります。


- (void)loadImage
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    self.img = [UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString: [myProduct objectForKey:@"ImagePath"]]]];
    [self setNeedsDisplay];
    [pool release];
}

これを drawRect 関数自体から呼び出すと (これは悪いことです)、「動作」しますが、これは明らかに何かが発生するたびに呼び出されます (選択など)。それをセルの uiview の init 関数に入れると、最初の 8 つのセルに対してのみ呼び出され、その後再利用されます。他のバリエーションでは、セルが再利用されたときに画像が「リセット」されないため、同じ 8 つの画像がテーブルの下に繰り返されます (ただし、他のテキストは更新されます)。

今のところキャッシュについて心配していませんが、これを行う方法のサンプルはありますか、誰かが私を正しい方向に向けることができますか? ありがとう。

4

5 に答える 5

2

デフォルトではUITableViewがセルをリサイクルするため、ソリューションはより洗練されたものになる必要があります(上からスクロールすると、下に移動され、新しいデータで再構成されます)。したがって、画像のダウンロードを開始しても、ダウンロードが完了する前にセルのコンテンツが変更される可能性があります。

ではcellForRowAtIndexPath:、キャッシュ(myProductオブジェクト、NSArrayなど)から画像を取得する必要があります。そこにない場合は、フラグをチェックして、すでにロードされているかどうかを確認する必要があります。まだロードされていない場合は、そのフラグを設定して新しいスレッドをデタッチします(調査する必要がありNSOperationます。これにより、作業がキューに入れられ、一度に多くのスレッドを起動するのを防ぐことができます)。

スレッドでは、画像をダウンロードしてから、を使用して画像を使用performSelectorOnMainThread:target:waitUntilDone:してメインスレッドのメソッドを呼び出す必要があります。このメソッドは、キャッシュを更新し、isLoadingフラグをNOに設定して、セルを更新できます。CocoaではすべてのUI更新コードがメインスレッド上にある必要があるため、この方法で行うことが重要です。

それが何をすべきかの有用な概要であることを願っています。

于 2009-11-15T17:56:33.137 に答える
1

これはあなたの質問に答えるはずです。LazyTableImages

于 2010-07-16T04:55:21.093 に答える
0

スタンフォード大学の講義cs193pからの適切なスライド/ビデオ/コードの例を見てください... iphoneアプリケーションプログラミング..。

于 2009-11-15T22:04:25.917 に答える
0

セルをデキューすると、そこに画像を強制的にロードできます。init内でそれを行う必要はありません...通常は次のようにします。

cell = dequeueCell...
if (!cell) {
   //create one
}

return cell;

あなたができることは、リターンセルの前にあります、それがあなたが望むセルのタイプであるならば、あなたは画像を強制的にロードすることができます。このように、表示されるたびに、キャッシュから取得でき(存在する場合)、表示されない場合は、Webにアクセスして取得できます。

于 2009-11-15T17:44:08.423 に答える