1

私はObjective-cに少し慣れていません。だから、私の質問やコードが奇妙に見えるなら、それは理由を説明するでしょう。0.033秒ごとに起動されるNSTimerがあります。

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

セレクター関数は次のようになります。

BOOL running = false;
- (void) timerCallback
{
   if (running) {
    return;
   }
   running = true;
   //Do some stuff
   running = false;
}

つまり、同期を維持するものに関係なく、関数timerCallbackをこれらの間隔で起動する必要があります。(詳細はスキップ)

しかし...結局のところ、timerCallback関数により、NSTimerが停止し、完了するのを待ってから再開しますか?

間隔を維持するにはどのようなオプションが必要ですか?timerCallback関数を別のスレッドで実行できますか?NSTimerよりも優れたオプションはありますか?おそらく、そもそも別のスレッドですか?

4

2 に答える 2

2

ブロックを防ぐために、このようなものを使用することをお勧めします。

BOOL running = false;
- (void) timerCallback
{
   if (running) {
    return;
   }

  [(NSOperationQueue*)_myOperationQueue addOperationWithBlock:^{
     running = true;
     //do Some Stuff
     running = false 
  }];
}
于 2012-08-22T12:31:20.187 に答える
0

タイマーは、NSTimer と NSRunLoop の設計により正確なタイミングを提供できないため、時間の経過とともに平均化された目的の起動間隔を維持しようとします。タイマーのコードが 0.033 秒以上かかっている場合、タイマーが 1 つの呼び出しをスキップするかどうかはわかりません。

この実験を試してみてください - タイマーを設定してから、すべての作業をコメントアウトして、時間を記録してください。希望の時間に非常に近いはずです。とはいえ、1 秒あたり 30 回の呼び出しで、UI にまったく触れている場合、これは期待できる最大のパフォーマンスに近いものです。

変動量を最小限に抑える 1 つの戦略は、実行中のすべてのコードをブロック内に配置し、それをメイン キューにディスパッチするか、できれば並行スレッドにディスパッチすることです。そうすれば、非常に短い時間で通話から戻ることができます。

これでうまくいかない場合は、CADisplayLink をご覧ください。この機能は非常に高い優先度で実行されるため、この機能を使用して非常に正確なコールバックを取得できます。ただし、ほんのわずかな時間しか得られないため、コールバックで実質的なことを行うことはできません。ただし、ブロックをキューにディスパッチして、メイン キュー (メイン スレッド) で処理することはできます。

于 2012-08-22T11:44:47.953 に答える