9

プリフェッチに比較的コストがかかるデータベースからデータを取得する UITableView があります。この問題に対処するために、LazyTableImagesサンプル コードのデザイン アイデアを使用して、 [UITableView visibleCells].

これはパフォーマンスの点ではうまく機能しますが、解決したい相互作用の問題が 2 つあります。

  1. スクロールが完全に停止するまで (つまりscrollViewDidEndDecelerating)、データはロードされません。したがって、リストをゆっくりとスクロールする場合は、スクロールを停止して、データを表示されているセルにロードする必要があります。理想的には、スクロールが遅い速度で行われている場合、データをセルにロードします。
  2. スクロールすることを見越して、画面外にある1つまたは2つのテーブルセルデータをプリフェッチしたいと思います。

これを達成するエレガントな方法はありますか?この問題の一般的な設計パターンが欠けているのではないかと感じています。

4

5 に答える 5

6

スクロールの開始と同時にデータのロードを開始できるので、スクロールが終了するのを待つ必要はないと思います。次の 2 つの方法のいずれかを使用できます。

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{}

また、いつでも可視セルのインデックスを取得できるので、可視セルだけでなく、さらにいくつかのデータをロードできるはずです。

于 2012-11-20T15:38:43.073 に答える
2

LazyTableImages コードをそのまま使用している場合、それは正常です。読み込みは、スクロールが終了するまで延期されます。私のテスト アプリ (単純な instagram のようなストリーム) では、別のアプローチを使用します。基本的には、セルをサブクラス化し、セル自体からダウンロードを開始し、セルをダウンロード マネージャーのデリゲートとして使用してから、セルの UI を更新します。ダウンロードが終わったら

詳細に

  • cellForRowAtIndexPath メソッドでダウンロードを開始します (ビューがスクロールしている場合、LazyTableImages はダウンロードを延期します。スクロール中にロードしても問題ないため、ダウンロードを延期しません) セルの「startDownload」メソッドを呼び出します。
  • 私のセル サブクラスはダウンロード マネージャーのデリゲートとして設定され、ダウンロードが完了すると、セルはプレースホルダーを実際の画像に変更します (これはカスタムの "downloadManagerDidFinishDownloadForImage:(UIImage*)image" デリゲート メソッドで実行され、細胞サブクラス)
  • 私のセル サブクラスでは、prepareForReuse メソッドをオーバーライドします。ここで、セルが再利用される場合は、ダウンロードを停止することを選択できます。私の場合、デリゲートの設定を解除し、ダウンロードを続行します。これは、コア データで作成された画像キャッシュがあり、キャッシュを続行したいからです。

さらに、次の 2 つの点に注意する必要があります。

  • ダウンロード マネージャーはバックグラウンド スレッドで動作する必要があります
  • メインスレッドでセル UI を更新してください。使用できます

:

dispatch_async(dispatch_get_main_queue(), ^{
    //update here your cell UI
});

デリゲート メソッドで (そのメソッドがダウンロード マネージャーによって呼び出された場合は、必ずバックグラウンド スレッドで呼び出されるため、ディスパッチを使用してメイン スレッドで「移動」する必要があります)。

必要に応じて、私の例を見ることができますが、それは「そのまま」です(これはテストアプリであり、スパゲッティコードと質問に関係のないものがたくさんあります;-)

http://www.lombax.it/documents/InstaXplore.zip

私の例では、次を確認する必要があります。

  • BrowseCell <-- セルのサブクラス
  • BrowsePhotoViewController <- テーブルビューコントローラー

他にもコアデータストレージやインスタグラム関連ですが、基本的には

  • cellForRowAtIndexPath で新しいセルを作成 (または前のセルを再利用) し、InstaImage アイテム (カスタム イメージ) を渡します。
  • InstaImage は、キャッシュされたコピーが存在するかどうかを確認し、存在しない場合はダウンロードを開始し、セルに警告を返します

何度も試すためのキャッシュクリアボタンがあります:-)

于 2012-11-20T10:51:12.420 に答える
1

レイジーイメージロジックは、以前はテーブルビューで使用していた優れたソリューションですが、最近はUITableViewにさまざまなソリューションを実装しています。1つ目は、AppleがWWWDCで提供しているこのビデオのようなNSOperationキューを実装することですhttps://developer.apple.com/videos/wwdc/2012/?include=211#211

または、無限スクロールを作成してみてください。uitableviewcellに到達すると、より多くのデータを含む新しい「ページ」が読み込まれます。このソリューションについてサポートが必要な場合は、お知らせください。

お役に立てれば!

よろしくお願いします、

ホルヘ。

于 2012-11-24T05:07:44.383 に答える
1
// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;



(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate)
    {
        //fetch data for visible rows
    }
}
于 2012-11-18T15:53:00.923 に答える