質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

2103閲覧

ストップウォッチアプリの時間の計算方法について質問です。

tatuya51

総合スコア23

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2020/04/26 06:04

サンプルのストップウォッチアプリを作成していたのですが、時間の計算(加算)方法がなぜ
updateメソッドの「Date.timeIntervalSinceReferenceDate - startTime」のような計算式になるか理解できません。

swift初心者の私的には基準となる数字(0)を宣言して、startTimerメソッドで0.01秒ずつ加算していけばいいのでは??
と感じたのですが、具体的に何が起きているのでしょうか?

ご回答よろしくお願いいたします。

swift

1 @objc func update() { 2 // 2001/1/1 00:00:00 3// print(Date.timeIntervalSinceReferenceDate) 4 print(#function) 5 if let startTime = self.startTime { 6 let t: Double = Date.timeIntervalSinceReferenceDate - startTime 7 print(t) 8 } 9 } 10 11 12 @IBAction func startTimer(_ sender: Any) { 13 self.startTime = Date.timeIntervalSinceReferenceDate 14 Timer.scheduledTimer(timeInterval: 0.01, 15 target: self, 16 selector: #selector(self.update), 17 userInfo: nil, 18 repeats: true) 19 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

swift初心者の私的には基準となる数字(0)を宣言して、startTimerメソッドで0.01秒ずつ加算していけばいいのでは??

と感じたのですが、具体的に何が起きているのでしょうか?

0.01秒ずつタイマーイベントを発生させて、その中でカウンタを+0.01するという方法ですが、
そもそもタイマーイベントはそのスレッドの暇な時間に呼ばれるのであって、
必ず0.01秒ごとに呼ばれるという保証はありません。
そのため誤差が蓄積し、正確な時間が計測できません。
(と言ってもiPhoneのタイマーイベントはかなり性能が高い方です。Windowsはもっと酷いので。)

精度が求められない場合であればカウンタに足していく方式でも良いですが、
ストップウォッチのような精度が求められるようなものであれば、
経過時間 = 現在の絶対時間 - スタート時の絶対時間のような式を使うべきです。
これであれば、誤差が蓄積するということはありません。

投稿2020/04/26 08:12

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatuya51

2020/04/26 12:36

ご回答ありがとうございます。 とてもわかりやすい説明で理解することができました。 ちなみに0.01秒づつ足していくパターンも作成してみたのですが、それっぽい時間には一応なるものの厳密には正確な時間を測れていないのですね、、 最初に具体的に回答してくださったのでベストアンサーにさせていただきます。
guest

0

takabosoftさんの回答+αになりますし、参考にされているアプリの作り方にどのように記述されているのか、その文脈が読めないので推測の上での回答になりますが、こんなこともあります。

scheduledTimerは、たとえばアプリがバックグラウンドに入ってしまった場合には呼び出されません。

なので、バックグラウンドに入っていた間の経過時間も確実に計測したいのであれば、やはり基準時刻を元に計算する方法が確実になります。


なぜ0.01秒ごとに呼び出されているのか疑問に思われのは当然かもしれません。

しかし、たとえば呼び出しごとに自分で累積させた(呼び出しごとに0.01加算させた)時刻と、基準時刻から引き算した時間を表示させてみると、その違いに気づくこともあります。

例えば、この場合はアプリをバックグラウンドに入れてみるなどです。

今回の場合も、是非簡単なサンプルコードを作ってみて、ご自身で確認されることをお勧めします。

投稿2020/04/26 08:45

TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatuya51

2020/04/26 12:45 編集

ご回答ありがとうございます。 早速簡単な形で0.01加算させるパターンを作成してみましたが、確かにバックグラウンドに入れた瞬間止まってしまいました。(再度画面を開いたら再開しました) 今回もとても勉強になりました。 また機会がありましたらご回答よろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問