2

を使用して自分自身を描画する単純なUIViewがありますdrawRect:。ビューをアニメーション化するには、drawRectたとえば0.05秒ごとにメソッドを呼び出す必要があるため、繰り返しタイマーを使用します。

timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self 
        selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];

実行ループ、スレッド、およびそれらすべてのシステムに関することについてあまりよく知らないので、これがアニメーションを実行する正しい方法であるかどうかを知りたいですか?このタイマーは際限なく繰り返されます。これは私が心配すべきことですか?これはメインスレッドをブロックしますか?パフォーマンスへの全体的な影響を最小限に抑えるために何ができますか?

4

2 に答える 2

2

アプローチは悪くありませんが、他の方法があります。

タイマーのターゲットメソッドはタイマーを引数として受け取る必要があるため、setNeedsDisplayに直接設定するのではなく、次のようなメソッドを設定する必要があります。

- (void)animationTimerDidFire:(NSTimer *)timer
{
    [myView setNeedsDisplay];
}

ビューが常に表示される場合は、タイマーを設定して忘れることができます。一方、別のビューに切り替えたためにタイマーが消える可能性がある場合は、必要に応じてタイマーを無効にして再作成する必要があります。

アプリのメインスレッドは実行ループを使用し、ユーザータップ、システム通知(メモリ警告など)、I / Oの到着などのイベントに応じて、さまざまなメソッドを呼び出します。実行ループ呼び出しが戻るのに長い時間がかかる場合は、キュー内のすべてを保持します。タイマーを設定すると、タイマーがリストに追加され、実行ループが毎回タイマーをチェックします。タイマーの1つが準備できている場合、それはあなたのメソッドを呼び出します。

最終的に、タイマーは正確ではなくなります。タイマーは、必要な頻度で起動されない、遅く呼び出されるなどの可能性があります。繰り返しになりますが、アプリが非常に単純な場合、メインの実行ループはそれほどビジーではないため、タイマーが使用されます。おそらく十分でしょう。各呼び出しが正確に0.05秒間隔で発生すると想定するのではなく、アニメーションが呼び出し間の実際の経過時間に基づいていることを確認してください。

代替案

アニメーションに静止画像のめくりが含まれるだけの場合、UIImageViewはこれをある程度サポートしています。

アニメーションの各フレームの作成にかなりの時間がかかる場合(メインスレッドをブロックしたくない場合)、バックグラウンドキューを使用して画像に描画し(CGBitmapContextCreateおよびを参照CGBitmapContextCreateImage)、新しいときにメインスレッドに信号を送ることができます。画像を表示する準備ができました。ビューに触れるものはすべてメインスレッドで発生する必要がありますが、背景で描画を行うことができます。

CALayerまた、QuartzCoreフレームワークを読み進めることもできます。これは、UIViewオブジェクトが実際に操作して画面に描画するものです。描画する代わりに、いくつかのCALayerオブジェクトを操作し、Core Animationに手間のかかる作業を行わせることで、必要な効果を得ることができます(たとえば、色を赤から青に変更すると、CoreAnimationが1から青へのフェードを処理します。他)。

于 2012-06-25T21:09:18.053 に答える
0

オーバーライドまたはカスタムメソッドを使用している場合は、アニメーションを呼び出すために再帰と完了ブロックを使用する必要があります。タイマーは常に正確であるとは限らず、アニメーションのタイミングをサイクリングする場合、アニメーションの問題が発生する可能性があるため、タイマーよりもはるかにうまく機能することがわかりました。

編集:drawRect:を使用して[self setNeedsDisplay]を呼び出して更新することについてはよくわかりません。そのため、その点についてはお役に立てません。ごめん。

于 2012-06-25T21:06:43.660 に答える