1

アプリがバックグラウンドで計算を行っている間に、いくつかの読み込みポイントをアニメーション化したいと思います。私はこれを介して達成しますNSTimer:

    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.3f
                                             target:self 
                                           selector:@selector(updateLoadingPoints:) 
                                           userInfo:nil 
                                            repeats:YES];

残念ながら、計算が非常に重くなると、メソッドが起動されず、更新が行われないことがあります。すべての発射は、重い計算の後に発射されるキューにあるようです。

NSTimer私のメソッドを定期的に呼び出していることを確認するために、より高い優先度を与える方法はありますか? または、これを達成する別の方法はありますか?

4

4 に答える 4

3

NSTimerは、メイン実行ループのキューにイベントを追加することで機能します。これは、タッチイベントやI/Oデータ受信イベントなどに使用されるのと同じイベントキューです。設定した時間間隔は正確なスケジュールではありません。基本的に、実行ループを通過するたびに、タイマーがチェックされ、起動される予定があるかどうかが確認されます。

それらの実装方法のため、タイマーの優先度を上げる方法はありません。

セカンダリスレッドがメインスレッドから多くのCPU時間を奪っているように思われるため、タイマーは必要な頻度で起動しません。つまり、メインスレッドはCPU時間に飢えています。

これらのメソッドは基本的にシングルファイアタイマーをメインスレッドのイベントキューに追加するため、呼び出しperformSelectorOnMainThread:は必ずしも役立つとは限りません。したがって、タイマーを別の方法で設定するだけです。

問題を解決するには、計算スレッドの優先度を下げて、メインスレッドの相対的な優先度を上げることをお勧めします。(を参照してください。)[NSThread setThreadPriority:]

重要なワーカースレッドをメインスレッドよりも低い優先度で実行するのは直感に反するように思われるかもしれません。メインスレッドは画面に何かを描画するだけですが、人間に優しいアプリケーションでは、画面を最新の状態に保ち、ユーザー入力に応答します。通常、アプリが実行する必要がある最も重要なことです。

実際には、メインスレッドはCPUをほとんど必要としないため、ワーカースレッドの速度が低下することはありません。むしろ、メインスレッドが何かを実行する必要があるわずかな時間の間、それが迅速に実行されることを保証しているだけです。

于 2012-01-09T19:47:26.170 に答える
0

タイマーは、スケジュールされている実行ループに追加されます。セカンダリ スレッド (ワーカー スレッドなど) でタイマーを作成する場合は、セカンダリ スレッドでもスケジュールする可能性が高くなります。

メイン スレッドで UI の更新が必要です。したがって、メインスレッドでタイマーをスケジュールする必要があります。更新がまだ遅い場合は、おそらくメイン スレッドが行う作業が少なくなり、スレッド数が非常に少なくなり、適切にロックされていることを確認できます。

タイマーが起動したいほど頻繁に実行ループを実行しなかったセカンダリスレッドで作成したと思われます。バックグラウンドで多くの (長時間の) 作業を行っていて、実行ループを実行していない場合、スレッドがまだ処理されていない間はメッセージが起動される機会がないため、タイマーが起動する機会がありません。 .

于 2012-01-09T22:17:48.567 に答える
-1

performSelectorInBackground:withObject を使用して、別のスレッドで計算を実行します。UI ループでの作業は常にできる限り少なくしてください。ここで行われる作業は、マウスクリックを防ぎ、SPoD/ビーチボールを引き起こし、タイマー ハンドラーを遅らせます。

TIMER が応答しないだけでなく、UI 全体が一般的であると思われます。

以前のリビジョンで間違った API を呼び出してしまったことをお詫びします。コピー/貼り付けの失敗です。

于 2012-01-09T19:27:30.610 に答える
-1

メインスレッドからではなく、別のスレッドからタイマー呼び出しを行います。これにより、他のメインスレッドの処理から確実に分離され、望ましい結果が得られます。

于 2012-01-09T10:37:02.083 に答える