プログラミングで何か作っていれば、タイマーが必要になることは割とあるのではないかと思います。
Swiftのタイマーは簡単に使うことができるのですが、いくつか注意点があります。
場合によってはメモリリークを起こしたり、タイマーのずれが発生して困るかもしれません。
Timerの使い方
使い方は簡単です。
まずは全体的なサンプルコードです。
import UIKit
class ViewController: UIViewController {
var sampleTimer: Timer?
var count: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
cleateTimer()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("second view will disappear")
if sampleTimer != nil {
sampleTimer?.invalidate()
sampleTimer = nil
}
}
@IBAction func backToFirst(_ sender: Any) {
dismiss(animated: true)
}
func cleateTimer() {
sampleTimer = Timer.scheduledTimer(timeInterval: 1.0,
target: self,
selector: #selector(self.countUp),
userInfo: nil,
repeats: true)
RunLoop.main.add(self.sampleTimer!, forMode: .common)
}
@objc func countUp() {
count += 1
print("\(count)")
}
}
この中で最低限必要なのは3つあります。
まずは、Timerオブジェクトを用意します。
var sampleTimer: Timer?
それから、次のようにして、タイマーを生成します。
sampleTimer = Timer.scheduledTimer(timeInterval: 1.0,
target: self,
selector: #selector(self.countUp),
userInfo: nil,
repeats: true)
あとは、タイマーで呼び出す関数を用意します。
@objc func countUp() {
count += 1
print("\(count)")
}
Timer.scheduledTimerの設定を変えることで、タイマー動作を変更できます。
timeInterval | タイマー間隔です。上記のサンプルの場合、1秒間隔で動作します。 |
repeats | タイマーを繰り返すかどうか。falseにすると一回だけ動作します。 |
Timerの注意点
Apple Developerサイトをによると、次のような注意点があります。
Timer | Apple Developer Documentation
A timer that fires after a certain time interval has elapsed, sending a specified message to a target object.
精度やタイマーの後始末に気をつける必要がある、ということですね。
タイマーを破棄して後始末
タイマーを無効にしていないと、メモリリークを起こす場合があります。
不要になるタイミング(View will disappear等)で破棄するようにしましょう。
タイマーを破棄するにはinvalidate()を使います。
if sampleTimer != nil {
sampleTimer?.invalidate()
sampleTimer = nil
}
精度について
特にUIでスクロール処理をしている場合に、タイマーにずれが発生するので注意が必要です。
次のようにすると、対策できます。
sampleTimer = Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(self.countUp),
userInfo: nil,
repeats: true)
// 下記を追加
RunLoop.main.add(self.sampleTimer!, forMode: .common)
コメント