24

アプリをほぼ完成させたところですが、ベータ テストでストップウォッチ部分にバグが見つかりました... ストップウォッチは nstimer を使用してカウントを行い、ラップを保存するためのテーブルを持っていますが、ラップ テーブルをスクロールすると時計が停止または一時停止します失われた時間を取り戻せません。

これは、以下を使用して停止していました。

startingTime = [[NSDate date] timeIntervalSince1970];

経過時間を計算します。

しかし、私はまだ NSTimer を使用して 0.1 秒ごとにトリガーしています。これは、経過時間が最後に正しく更新されても、スクロールによってタイマーが停止することを意味します...これを Apple ストップウォッチと比較すると、ストップウォッチには、経過時間をカウントするためだけの別のスレッドがあります。それがどのように行われるかを誰かが知っていますか?

現在、エポック以降の時間を使用することは、ある意味ではうまく機能していますが、ストップウォッチの開始、停止、再起動の問題が複雑になります

時計が停止すると、時間が保存され、時計が再起動されたときのオフセットを計算するために使用されますが、遅延が発生しているようで、時計を再起動すると時間が目に見えて進みます。

根本的な原因または解決策に向けた考えは大歓迎です。

4

2 に答える 2

48

bbum の答えは、アプリケーションを設計するためのより良い方法を提供しますが、ユーザーが UI を操作しているかどうかに関係なくタイマーを起動させたい場合は、ランループの追跡モードに追加する必要があります。

iPhone 向けに開発していると仮定すると、そのモードはUITrackingRunLoopMode. Mac 用に開発している場合は、同様の名前のNSEventTrackingRunLoopMode.

NSRunLoop *runloop = [NSRunLoop currentRunLoop];
NSTimer *timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(myTimerAction:) userInfo:nil repeats:YES];
[runloop addTimer:timer forMode:NSRunLoopCommonModes];
[runloop addTimer:timer forMode:UITrackingRunLoopMode];
于 2010-01-04T01:03:51.587 に答える
22

イベント ループが実行されていない場合、イベント ループが再び実行されるまで、タイマーは起動しません。イベント ループがブロックされていない場合でも、タイマーが構成された間隔で正確に起動するとは限りません。タイミングが完全にタイマーの起動に基づいていた場合、エラーの量は時間の経過とともに大きくなります。

タイマーの起動とは別に期間を追跡する必要があります。タイマーが作動するたびに、持続時間を再計算して再表示します。

開始/一時停止/再開/停止タイプのセットアップでは、通常、次のことを行います。

  • 開始時の時間を取得します (NSDate インスタンスまたは NSTimeInterval 値として)

  • 一時停止または停止時に、一時停止/停止時に時間を取得します。この時間から開始時間を引くと、インターバルの継続時間が得られます

  • 再起動時に、再起動時に時間を取得しますが、すでに経過した期間も保持します

  • 一時停止/停止時に、一時停止/停止時の時間を取得し、すでに経過した時間を追加します

一般に、これらすべてを NSTimeInterval 値 (単なる double) で行うのが最も簡単です。ただし、イベントが発生した実際の瞬間を追跡する必要がある場合は、代わりに NSDate インスタンスを使用してください。

于 2010-01-03T18:48:28.783 に答える