8

iOS で画像のパフォーマンスをテストするアプリを作成しました。私は 3 つの異なるビューを試しましたが、すべて同じ大きな PNG を表示しています。1 つ目は、CGContextDrawImage() を使用して描画するビューです。2 番目は、self.layer.content を設定します。3 つ目はプレーンな UIImageView です。

使用される画像は、-[UIImage initWithContentsOfData:] を使用して作成され、viewController にキャッシュされます。各テストでは、ビューの割り当て、ビュー階層への追加、および削除と解放を繰り返します。タイミングは、loadView の開始から viewDidAppear まで取得され、fps として指定されます (事実上、1 秒あたりのビューの描画数)。

912 x 634 のスケーリングされていない画像を使用して、5.1 を実行している iPad 1 の結果を次に示します。

CGContext:    11 fps
CALayer:      10 fps
UIImageView: 430 fps (!)

私は幻覚ですか?UIImageView がそれほど高速に描画できることはほぼ不可能に思えますが、実際に画像がちらつくのを見ることができます。キャッシングの可能性をなくすために 2 つの類似したビューを交換しようとしましたが、フレーム レートはさらに高くなりました。

UIImageView は -[CALayer setContent] の単なるラッパーだといつも思っていました。ただし、UIImageView のプロファイリングでは、特定できる描画方法に費やされた時間はほとんどありません。

何が起こっているのか理解したいです。どんな助けでも大歓迎です。

4

3 に答える 3

1

UIImageView で FpS が高いのは、これが実際に再描画するのではなく、将来 UIKit がやりたいと思ったときに再描画するコンテンツをマークするだけだからです。

注: 奇妙なことに、CGContext メソッドは CALayer メソッドよりも高速です。私のプロジェクトでもこれらの方法を試しましたが、CALayer で作業するのが最速の方法です (もちろん OpenGL ES を使用する場合を除く)。

于 2012-11-12T13:01:31.030 に答える
1

これが私の考えです。

ビューを追加、削除、または変更して UIView 階層を変更すると、実際の描画はまだ実行されません。代わりに、ビューは「setNeedsDisplay」でマークされ、次回実行ループが自由に描画できるようになったときに再描画されます。

実際、テスト コードが次のようになっているとします (推測するしかありません)。

for (int i=0; i<10000; i++) {
     UIImageView* imageView = [[UIImageView alloc] initWithFrame:frame];
     [mainView addSubview: imageView];
     [imageView setImage: image];
     [mainView removeSubview: imageView];
}

この for ループが完了するまで runloop はブロックされます。ビュー階層は 1 回だけ描画されます。測定されたパフォーマンスは、オブジェクトの割り当てと初期化のパフォーマンスです。

一方、CGContextDrawImage() は、すぐに自由に描画できると思います。

于 2012-04-19T06:06:32.533 に答える
0

UIImageView は、はるかに効率的な画像をレンダリングする別の方法を使用します。レンダリング プロセスがどのように機能するかを説明する WWDC 2011 のセッション ビデオをご覧ください: https://developer.apple.com/videos/wwdc/2011/?id=121

于 2012-05-04T13:57:09.747 に答える