18

多くのWWDCビデオで、よりスムーズなスクロール体験を得るために、できるだけ60.0FPSを達成したいと言っています。画像といくつかのテーブルビューを一度にロードするUIScrolLViewがあります。現在、30FPSを取得しています。これは、推奨されるFPSの半分です。画像やその他の重いもの/レンダリングのものをロードするテーブルビュー/スクロールビューで、通常どのFPSが得られるのか疑問に思っています。

FPSを最適化するための他のヒントはありますか?私はこの1週間、タイムプロファイラー、割り当て、コアアニメーションツールを使用してInstrumentsを起動し、可能な限り最適化することに費やしました。

私が持っているものを少し明確にするためだけに。iPadに石積み/滝/ピンタレストスタイルのレイアウトがあります。したがって、これは通常のUITableViewだけではありません。これは、画面全体を埋めるUIScrollViewであり、いくつかのUIViewで埋められます。この各ビューには、150x150のUIImageViewとUITableViewがあり、CoreTextを使用して描画された属性付きのラベルもあります。したがって、画面を見ると一目で5〜8個のテーブルビューを一度に確認できます。各セルには再びUIImageViewがあり、各セルはコアテキストを使用して描画された属性付きラベルをレンダリングします。

したがって、これがどれほど深く複雑であるかを想像することができます。これは、UIImageViewを使用した通常のテーブルビューだけではありません。UIImageを備えたiPhoneで1つのUITableViewだけで60FPSを取得する方法を知っています。コンセプトは、画像を非同期でロードし、メインスレッドをできるだけブロックしないことです。

編集:

ここでの問題は、ビュー内にあるUITableViewにあるようです。UIViewからそれを削除すると、非常にスムーズなスクロールが得られます。

私が持っているもののより単純なバージョンであるサンプルプロジェクトをアップロードしましたが、それは明らかに問題を示しています。リンクはこちら

4

8 に答える 8

20

レンダリングのパフォーマンスには多くの影響があります。確認できる項目は次のとおりです。

  • プロフィール-あなたはすでにこれをしたと言ったので、素晴らしい仕事です!残念ながら、プロファイリングは予期しない問題を明らかにする可能性がありますが、見過ごされがちです。あるアプリでは、日付を表すさまざまなセルを使用してカレンダーを作成していました。最初はセル間のスクロールが遅くなりましたが、これは予想外でした。数個のセルを描画しすぎているのではないかと思いました。プロファイリング後[NSCalender currentCalender]、CPU時間の85%を使用していることがわかりました。それを修正した後、すべてがうまくスクロールしました!

  • 画像-大きな画像はCoreGraphicsに大きな負荷をかけます。スクロールは、それらを移動するために特に多くの描画操作を必要とします。1つのヒントは、デバイス上の画像をできるだけ小さく拡大縮小することです。これにより、CoreGraphicsの作業がはるかに簡単になります。画像が表示されているビューの2倍の大きさの場合は、ビューに表示する前にUIImageのサイズを変更してください。iOSデバイスはPNGを最もよく処理します。それらはコンパイル時にツール(pngcrush)によって圧縮され、iOSにはそれらをレンダリングするための特別なハードウェアがあります。

編集:JPGはおそらく写真のためのより良いオプションです。iOSデバイスには専用のJPGデコーダーもあります。

  • カスタム描画-可能であれば、実行するカスタムCGContext描画の量を削減します。多くのカスタム描画は、アニメーションの速度に悪影響を及ぼします。可能であれば、複雑なカスタム描画の上に画像を使用することを検討します。

  • カル-必要なものだけを描きます。UITableViewセルが表示されたときに自動的にアンロードおよびロードされるため、これは自動的に行われますが、カスタムCGContext描画は、その部分が表示されている場合にのみ実行する必要があります。また、私の経験では、自動ビューシャドウは非常に遅くなる可能性があります。

  • 再利用-で再利用識別子を使用します。これにより、スクロール時に再割り当てするのではなく、セルオブジェクトを再利用UITableViewできます-この質問の答えを見てください。また、同じファイルに複数を割り当てるのではなく、再利用します。画像を自動的にキャッシュしますが、ファイルはキャッシュしません。UITableViewUIImagesimageNamedimageFromContents

  • 独自の作成-画面から隠されたサブビュービューをカリングし、遅延コンテンツの読み込みでスクロールする独自のグリッドビュークラスを作成できます。カスタムソリューションを作成することで、プロセスを完全に制御し、使用状況に合わせて最適化された設計を作成できます。ほとんどのユースケースでは、Apple標準よりも優れたものを構築するのに苦労しますが、特定のケースでそれが行われるのを見てきました。

  • 最後の手段-問題のあるビューのサイズを縮小し(ろ液を改善)、コンテンツを複数のページに分割し、画像を縮小し、パフォーマンスの低い古いデバイスを切り取ります。そのほとんどを犠牲にする前に、30FPSで解決します。デバイスは引き続き高速になり、古いデバイスは削除され、アプリは徐々に高速になります。

于 2012-08-04T05:24:16.437 に答える
7

UITableViewControllerテーブルに約2000個のセルが含まれ、各セルがWebから画像を取得する場合、60fpsに近づきます。秘訣は、必要に応じて画像を遅延ロードすることです。Appleのこのサンプルコードは非常に役立ちます。

一般的な考え方は、メインスレッドをブロックしないことでUIの応答性を維持することです。別のスレッドでダウンロードやその他の時間のかかるタスクを実行します。

于 2012-07-28T19:23:47.720 に答える
4

遅延読み込みと呼ばれる処理を実行します。これは、実際に表示されるまで画像を読み込みません。

これを行う方法の良い例は次のとおりです:http://www.cocoacontrols.com/platforms/ios/controls/mhlazytableimages

幸運を!

于 2012-07-28T19:21:51.363 に答える
3

私がやったことは、NSCacheを使用することです。NSCacheデータプロトコルに準拠するプロパティを持つ小さなクラスを作成しました(非常に簡単です)。つまり、メインテーブルの各セルと、キャッシュする価値のあるさまざまなもの(NSAttributed文字列、画像など)との間に関係を作成することです。これは、作成に手間がかかるものです。プリロードはしませんが、できます。

テーブルビューでセルを提供するように求められたら、キャッシュでプライマリオブジェクトを探します。そこにある場合は、必要なすべてのオブジェクトをプルします。キャッシュにオブジェクトがない場合は、古い方法でデータを取得しますが、終了する前に、データもキャッシュに保存します。

これは、セルをスクロールするときの「スタッター」を減らすのに本当に役立ちました。また、セル内でパフォーマンスを低下させるものをアニメートしないでください。すべてが完全にレンダリングされる必要があります。

もう1つ覚えておくべきことは、不透明に設定できるビューのプロパティがYESに設定されていることを確認してください。これは確かに、システムがセルをレンダリングするのに役立ちます(使用する場合は背景ビューを含む)。

編集:

そのため、UITableViewsが根本的な問題である可能性があることを含む情報を提供しました。したがって、2つの提案:

1)一歩下がって、scrollViewを単一のUITableViewにする方法を理解できますか?テーブルのヘッダーとフッター、セクションのヘッダーとフッター、そして基本的にセルをフローティングビューにする機能でさえ、自分が持っているものを再設計する方法を理解できませんか?

2)それで、あなたは提案1にノーと決める。それから、これをする。テーブルビューで使用されるスペースは、コンテナビューであると考えてください。テーブルビューを編集するときはいつでも、テーブルビューの画像スナップショットを取り、この画像を保持します。ユーザーがスクロールを開始したらすぐに、tableViewsを画像と交換します。scrollViewが停止したら、UITableViewを元に戻します。もちろん、これには微調整が必​​要です。実際、スクロール中に不透明な画像のスナップショットをテーブルにオーバーレイすることができます(これにより、テーブルが非表示になり、描画を求められるのを防ぐことができます)。

于 2012-07-28T20:49:35.160 に答える
1

人間の目は約60FPSで表示されるため、推奨されますが、30 FPSは、特に通常のユーザーが表示している場合は、可能な限り修正するものを見つけようとするのではなく、非常にスムーズに表示されます。これは明らかにスクロールの速度に依存します。フレーム間の違いが数ピクセルの動きである場合、30 FPSで問題ありませんが、動きが速いとスムーズに表示されるためにFPSを高くする必要があります。

于 2012-08-06T17:38:33.887 に答える
1

テーブルビューのパフォーマンスを向上させるために、一般的に実行できることがいくつかあります。

1)UITableViewCellを描画するLoren Brichterの方法に切り替えます(より良いリンクがないため:http ://www.therefinedgeek.com.au/index.php/2010/12/21/fast-scrolling-uitableview-updates-for- ios-4-2 /

基本的に、彼のコードはすべて、すべてのセルコンテンツを1つの不透明なUIViewとしてレンダリングするだけです。これにより、UITableView(およびCoreGraphics)はUITableViewCellに非常にすばやくブラストできます。

drawRect:ですべてのセル設計を行いたくない場合でも、nibsを使用できますが、次のようになります。

  • すべてのサブビューが不透明にマークされていることを確認してください
  • 透明/半透明のサブビューはありません
  • アルファチャネル!=1.0fの画像はありません。

2)UIImageViewに画像を表示するためのスケーリングを行わせず、正しいサイズのUIImageを指定します

3)iOS 5以降を使用している場合は、特定のセルIDのペン先を登録できます。そうすれば、[tableView dequeueReusableCellWithIdentifier:]を呼び出すと、セルを取得することが保証されます。セルの割り当ては(Appleによると)より速く、より少ないコードを書くことができます:

- (void)viewDidLoad {
    UINib *nib = [UINib nibWithNibName:@"MyCell" bundle:nil];
    [self.tableView registerNib:nib forCellReuseIdentifier:@"MyCellIdentifier"];
}

// ...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"MyCellIdentifier";
    MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    // Commented out code is no longer needed
    //if (cell == nil) {
    //    cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    //}

    // setup cell

    return cell;
}

4)ウェブからダウンロードした画像を表示する

  • デフォルトの画像を表示します(実際の画像のダウンロード中に見るもの)
  • 別のスレッドでダウンロードを開始します(ヒント:GCDのdispatch_async()を使用してください)
  • 画像が届いたら、キャッシュして(ヒント:NSCache)、セルに表示します
    • すべての画像のダウンロード/メインスレッドのキャッシュオフを実行します。メインスレッドで行う必要があるのは、画像を設定することだけです(UIコードはメインスレッドにあることを忘れないでください!)

おそらく、非同期対応のUIImageViewを作成する(または既存のライブラリを使用する)ことをお勧めします。

EGOImageViewには非同期ダウンロードがありますが、ダウンロードのためにバックグラウンドスレッドにディスパッチする前に、メインスレッドでキャッシュルックアップ(ディスク上にあるため、コストのかかるディスクIOを意味します)を実行します。以前はこれを使用していましたが、これを処理するために独自のクラスセットを作成することになり、大幅に高速化されました。

-

これらに従うだけで、他のpplがここに書いたものを見ると、すぐにガラスのようにスクロールするテーブルビューが表示されます:)

于 2012-08-06T22:45:40.303 に答える
0

60 fpsが必要ですが、実際には30fpsはそれほどひどく見えません。しかし、私はスクロール中のより滑らかな外観のために60fpsを達成しようとします。

多くのパフォーマンス改善の可能性があり、それらはさまざまなチュートリアルでも示されています

于 2012-08-06T07:19:08.697 に答える
0

60 FPSが理想的ですが、Haloのようなゲームは30FPSで非常にきれいに動作します。Haloの戦場の混乱には、おそらく、あなたのような複雑なリストでさえ、ほとんどのリストよりも驚くべき、速い動きが含まれています!

于 2012-08-06T20:16:21.463 に答える