1

その中UITableViewCellに5つUILabelのaUIButtonUIImageView、セルを背景として塗りつぶすaがあります。性能が少し遅いようですので、使っCoreGraphicsて改善することを考えていました。asCoreGraphicsの代わりに使用すると物事がはるかに速くなるというのは本当ですか?はいの場合、なぜですか?UILabelsubViews

セルに影を描くための次のコードがあります。

[self.layer setBorderColor:[UIColor blackColor].CGColor];
[self.layer setShadowColor:[UIColor blackColor].CGColor];
[self.layer setShadowRadius:10.0];
[self.layer setCornerRadius:5.0];
[self.layer setShadowPath:[[UIBezierPath bezierPathWithRect:self.frame] CGPath]];
4

3 に答える 3

3

一般に、(Gavinが示したように)最初に、サブビューが実際にスクロールにジッターを引き起こしていることを確認する必要があります。

UITableViewCellのスクロールパフォーマンスをテストするとき、InstrumentsでTimeProfilerをよく使用します。左側のパネルでObjective-COnlyに切り替えて、メインスレッドで最も時間がかかっているものを確認します。サブビューの再配置(レイアウト)または描画に多くの時間が費やされている場合は、CoreGraphicsを使用する必要があります。代わりに割り当て/割り当て解除に時間が費やされている場合は、サブビューがどのように再利用されているかを調べてください。それらが再利用されていない場合、もちろんこれはパフォーマンスの問題を引き起こす可能性があります。

そしてもちろん、合成を検討する必要があります。サブビューが不透明でない場合(CoreAnimationインスツルメントでこれを特定)、パフォーマンスに深刻な影響を与える可能性があります。

また、シャドウは描画にコストがかかることを認識してください。実装によっては、フレームごとにシャドウが再描画される場合があります。最善のオプションは、CALayerシャドウが完全にラスタライズされ、パスが定義されていることを確認することです。これにより、ピクセルマスクからのライブ計算を行う必要がなくなります。

最後に、各サブビューのレイアウトと再描画が個別に速度低下を引き起こしていることを確認した場合、いくつかのポイント/説明があります。

  1. テーブルビューセルの描画ルーチンの実装は、Appleがビュー用に作成した高度に最適化された描画よりもおそらく遅くなります。したがって、UIImageView自体の描画を再実装する戦闘に勝つことはありません。代わりに、CoreGraphicsを使用して描画する場合、パフォーマンスの向上は2つの場所からもたらされます。a。)以前は不透明ではなかったビューの事前レンダリング、およびビュー描画サイクルのレイアウトフェーズで費やされる時間の削減-これにより、GPU/CPUのワークロードが削減されます。スクロール。b。)個々のビュー描画のCGコンテキストを切り替える時間の短縮。各要素が同時に同じグラフィックスコンテキストに取り込まれるようになり、スイッチングコストが削減されます。

  2. メインスレッドでCoreGraphicsを使用してdrawRectで描画すると、CPUを使用して描画されます。セルの複雑さによっては、これによって独自のジッターが発生する場合があります。代わりに、バックグラウンドスレッドで別のCGContextに描画してから、ワーカーをディスパッチして、描画の内容をCGImageRefとしてCALayerに挿入するか、UIImageとしてUIImageViewに挿入することを検討してください。GitHubにはナイーブな実装があります:https ://github.com/mindsnacks/MSCachedAsyncViewDrawing

  3. バックグラウンドのCoreGraphics描画を使用することにした場合は、現時点(2012年12月)では、バックグラウンドスレッドで描画するときに、NSString描画カテゴリにバグがあり、スレッドセーフではないWebkitへのフォールバックが発生すると思われることに注意してください。 。これによりクラッシュが発生するため、現時点では、非同期描画がシリアルGCD/NSOperationキューで実行されていることを確認してください。

于 2012-12-07T19:05:47.460 に答える
2

シミュレータで、[デバッグ] → [カラーブレンドレイヤー]を選択します。赤は悪いです、緑は良いです。

より正確には、赤はGPUがアルファブレンドを実行する必要があることを意味します。主なコストは、ピクセルを2回描画し、場合によっては余分なテクスチャを再フェッチするために必要なメモリ帯域幅にあります。完全に透明なピクセルは本当に悪いです。

コアグラフィックスに飛び込む前に検討する必要がある3つの修正(すべて赤の量を減らす):

  • 可能な場合は、ビューを不透明にします。背景がに設定されているラベルは、[UIColor clearColor]多くの場合、代わりに単色に設定できます。
  • 透明度のあるビューをできるだけ小さくします。ラベルの場合、これには-sizeToFit/-sizeThatFits:レイアウトの適切な使用と調整が含まれます。
  • 不透明な画像からアルファチャネルを削除します(たとえば、セルの背景が画像の場合)—一部の画像エディタはこれを行いません。これは、GPUがアルファテストを実行する必要があり、画像の背後にあるものをレンダリングする必要があることを意味します。

さらに、[カラーオフスクリーンレンダリング]をオンにします(おそらく、[カラーブレンドレイヤー]をオフにした後、見やすくなります)。オフスクリーンでレンダリングされたものは黄色で表示され、通常はレイヤーマスクを適用したことを意味します。これらはパフォーマンスに非常に悪い可能性があります。CoreAnimationがマスクされた結果をキャッシュするかどうかはわかりません。

最後に、設定することでCoreAnimationにセルをラスタライズさせることができますcell.layer.shouldRasterize = YES(網膜デバイスでも必要cell.layer.rasterizationScale = [[UIScreen mainScreen].scaleになる場合があります。これが自動的に行われるかどうかは忘れます)。主な利点は、簡単であり、CoreGraphicsで画像ビューを自分でレンダリングするよりも効率的であるということです。(テキストはCPUでレンダリングする必要があるため、ラベルのメリットは少なくなります。)

また、ビューアニメーションが影響を受けることに注意してください。CALayer.shouldRasterizeの設定が何をするかを忘れています(アニメーションのフレームごとに再ラスタライズする可能性があります。これは、画面に1回だけ描​​画される場合は少し無駄です)が、Core Graphicsを使用すると(デフォルトで)レンダリングが引き伸ばされますアニメーション中のコンテンツ。CALayer.contentsGravityを参照してください。

于 2012-12-07T20:14:21.433 に答える
1

ビューにあるものがパフォーマンスの問題を引き起こしていることを示唆するために、どのような証拠が必要ですか?これはあなたを吸い込む可能性のある深いブラックホールなので、問題はあなたが思っている場所にあることを確認してください。

すべてのデータをプリロードしていますか?画像を事前にダウンロードしましたか?あなたが説明していることは、UITableViewCellの速度低下を引き起こしてはなりません。Appleの開発者はあなたよりもはるかに賢いので、私はあなたがあなたの決定を裏付けるデータを持っていることを確認してください!

また、シミュレーター内でUITableViewCellが遅れており、実際のハードウェアに目立った違いはありません。

CoreGraphicsを使用すると、描画パフォーマンスが向上する可能性がありますが、間違って実行すると速度が低下する可能性もあります。テクニックを実行する方法については、高度なテーブルビューセルに関するAppleチュートリアルをご覧ください。

于 2012-12-07T18:17:51.700 に答える