2012-07-28 12 views
17

多くのWWDCビデオでは、よりスムーズなスクロール体験を得るためにできるだけ近くで60.0 FPSを達成したいと考えています。私は一度に画像といくつかのテーブルビューをロードするUIScrolLViewを持っています。現在、私は30FPSを得ています。これは推奨FPSの半分です。ちょうどあなたがFPSとは何ですか?あなたは通常、テーブルビュー/スクロールビューのために画像やその他の重いものを読み込んでいます。スクロールに適したFPSとは何ですか?パフォーマンスを向上させるためのヒントは何ですか?

FPSを最適化するためのその他のヒントはありますか?私は今まで、タイムプロファイラ、アロケーション、コアアニメーションツールを使用してInstrumentsを起動して、できる限り最適化するまで、過去1週間を過ごしました。

私が持っているものをちょっと明確にすること。私はiPad上に石工/滝/ pinterestスタイルのレイアウトを持っています。したがって、それは単なるUITableViewではありません。これは、画面全体を埋めるUIScrollViewであり、UIViewのいくつかで満たされています。このビューには150x150のUIImageViewとUITableViewがあり、Core Textを使用して描かれた属性付きラベルもあります。したがって、画面を見ると一度に5-8の表ビューが表示され、各セルはUIImageViewを持ち、各セルはコアテキストを使用して描かれた属性付きラベルをレンダリングします。

これは、どれだけ深く複雑であるかをイメージすることができます。これは、UIImageViewを使用した通常のテーブルビューだけではありません。私は、UIImageを備えたiPhoneでただ一つのUITableViewを使って60 FPSを得る方法を知っています。概念は、画像を非同期的にロードし、主スレッドを可能な限りブロックしないようにすることです。

EDIT:

私がUIViewのから、私は本当にスムーズスクロールを取得することを削除すると、ここでの問題は..私は私のビュー内持っているのUITableViewであると思われる。..

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

+0

多分これます。http://www.cocoacontrols .COM /プラットフォーム/ IOS /コントロール/ gmgridview(それはPinterestのようなものですか?) – sridvijay

+1

あなたもPSCollectionViewをコンパイルする必要があるように見える:https://github.com/ptshih/PSCollectionView – Eoin

答えて

19

多くの物事がここで、パフォーマンスに影響するレンダリングは、あなたがチェックすることができ、いくつかの項目です:

  • プロフィール - あなたはすでに、とても素晴らしい仕事をし、これをやりました!残念なことに、予期しない問題を明らかにすることはできますが、プロファイリングはしばしば見落とされます。あるアプリケーションでは、日付を表す異なるセルを持つカレンダーに取り組んでいました。最初は細胞間のスクロールが遅く、予期せぬことでした。私は多分細胞が多すぎると思っていたかもしれません。プロファイリングの後、私は[NSCalender currentCalender]が私のCPU時間の85%を使っていたことを発見しました!すべてのことがスクロールしたことを修正した後!

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

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

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

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

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

  • 最後の手段 - 問題のあるビューのサイズを縮小し(濾液を改善する)、コンテンツを複数のページに分割し、画像を縮小し、実行しない古いデバイスを切り捨てます。ほとんどのものを犠牲にする前に、私は30FPSに落ち着くだろう。デバイスはますます高速化され、古いデバイスは削除され、アプリは徐々に速くなります。

+2

私は別のものを追加したいことを理解するだろうbullet:メインスレッド上でブロッキング(同期ダウンロードなど)や重い操作を行わないでください。イベントやUIを処理するメインの実行ループをブロックしないようにしてください。 – Jilouc

7

私のUITableViewControllerで約60fpsになります。テーブルには約2000個のセルが含まれており、各セルはウェブから画像を引き出します。トリックは、必要に応じて画像を怠惰に読み込むことです。このsample code from Appleはかなり役に立ちます。

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

+0

はい、私は実際にそれをやりました。私もすべての画像のダウンロードを無効にする/表示し、まだ60 fpsを得ない – xonegirlz

+0

フレームレートの問題を理解する一つの方法は、フレームレートが許容されるまでアイテムを削除することです。次に、項目を1つずつ追加して、どの項目がフレームレートを落とすかを確認します。次に、そのアイテムで創造的なことをします。アイテムに含まれる内容を正確に把握することなく、何をすべきかを正確に言うのは難しいです。 – SundayMonday

+0

私のプロジェクトに関する詳細を上記に追加しました – xonegirlz

3

NSCacheを使用することです。私はNSCacheデータプロトコルに準拠した小さなクラスを作成しました(本当に簡単です)。ですから、私はメインテーブルの各セルとキャッシュに値するさまざまなものとの関係を作成します:NSAttributedされた文字列、イメージなど - 実際に作成する作業が必要です。私はそれをプリロードしないでください。

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

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

覚えておいてください - 不透明に設定できるビューには、そのプロパティがYESに設定されていることを必ず確認してください。それは確かに、システムがセルをレンダリングするのに役立ちます

EDITのために(使用している場合backgoundビューを含む。):

だから、UITableViewsかもしれない根本的な問題を含めた情報を提供しました。そこで2つの提案:

1)スクロールビューを単一のUITableViewにする方法を教えてください。表のヘッダーとフッター、セクションのヘッダーとフッター、さらに基本的にセルをフローティングビューにする機能さえあれば、自分が持っているものを再構築する方法を理解できませんか?

2)したがって、あなたは提案1を選択しないでください。次に、これを行います。テーブルビューで使用される領域はコンテナビューであると考えてください。テーブルビューを編集するときはいつでも、それのイメージスナップショットを撮り、このイメージを保持します。ユーザーがスクロールを開始するとすぐに、画像のtableViewを交換します。 scrollViewがスワップを停止すると、UITableViewが元に戻されます。これはもちろん、いくらか微調整を行います。実際には、スクロール中にテーブル上に不透明なイメージスナップショットを重ねて表示することができます(スクロールしないようにする)。

+0

私はセルのためのキャッシュのいくつかの側面を持っていますが、助けにはなりませんでした。私はオリジナルの投稿に、私が持っている問題をはっきりと示したサンプルプロジェクトをアップロードしました。あなたはそれを見ていくつかの時間を気にして持っていない私、それは非常によく、日曜日のコミットメントを持っている – xonegirlz

+0

感謝ですが、月曜日 –

+0

確かにかいま見を取るために喜んでいるだろう..私はあまりにも – xonegirlz

0

60fpsが必要ですが、30fpsは実際にはあまりにもひどいです。しかし、私はスクロールしながらスムーズな外観のために60fpsを達成しようとします。

も様々なチュートリアルで

0

を示している多くのパフォーマンス改善の可能性が、それはお勧めします理由ですので、人間の目は、約60 FPSで見ているが、特にとき、通常の30 FPSはまた、非常に滑らかに表示されますがありますできるだけ多くのものを見つけようとするのとは対照的に、ユーザーはそれを見ています。これは明らかにスクロールの速さに依存します。フレームとフレームの違いが数ピクセルの動きであれば、30 FPSはうまくいくでしょうが、動きが速ければ高いほどFPSは高くなります。

0

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

1

より良いテーブルビューのパフォーマンスを得るためにあなたが一般的に行うことができますがいくつかあります。

1)のUITableViewCellの(より良いリンクの欠如のために描くのローレン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:ですべてのセルデザインを行いたくない場合は、ニブを使用することはできますが、

  • は、すべてのサブビューが
  • 不透明とマークされていることを確認し任意の透明/半透明のサブビュー
  • は、アルファチャンネルを持つすべてのイメージを持っていない持ってはいけない!= 1.0F。

2)それを正しくサイズUIImage

3)あなたは上記のiOS 5を使用している場合は、あなたがのためにペン先を登録することができますを与える、UIImageViewは、あなたの画像を表示するために、任意のスケーリングを行うことはできません。特定のセル識別子。このように、[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)、およびセル
      01に表示実像)
    • スタート別のスレッドでのダウンロードをダウンロードしています
    • メインスレッドからすべてのイメージのダウンロード/キャッシュを行います。あなたは、メインスレッド上でやるべき唯一のものの画像を設定している(UIコードを覚えているが、メインスレッドにする必要があります!)

あなたはおそらく(非同期対応のUIImageViewを書きたいと思うでしょう既存のライブラリを使用してください)。

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

-

ただ、これらに従ってください、とか他の皆さんは、ここに書かれている、とあなたは時間がない中でガラスのようにスクロールするテーブルの景色を眺めることができます:)

関連する問題