LoginSignup
4

More than 1 year has passed since last update.

【Swift5】Timerを変数に保存しないでinvalidateする

Last updated at Posted at 2021-03-01

結論から言えばそんなに大したことない話なんですけど、意外と使うので備忘録としてアウトプット。

とっても便利なTimer

アプリを作るときには、何かしらの処理でほぼ必ず使うであろうTimer。
Swiftにも使いやすいTimer関数が用意されています。

ViewController.swift
class ViewController: UIViewController {

  var timer: Timer = Timer()
  var count: Int = 0

  override func viewDidLoad() {
        super.viewDidLoad()

        // 1秒毎にup()を実行
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.up), userInfo: nil, repeats: false)
  }

  @objc func up() {
        // 60秒経ったらタイマーを止める
        if count > 60 {
            timer.invalidate()
        } else {
            count += 1
        }
  }

}

こんな感じで変数にタイマーを保存して、後から.invalidate()してタイマーをストップ&破棄するのが基本的な使い方です。

毎回変数に入れるのだるくない?

ストップウォッチ的な奴は別ですが、上のサンプルみたいに「x秒後に一回処理を実行する」みたいなパターンではすぐにタイマーを破棄することになるのでいちいち変数に入れるのはめんどくさいですよね。
しかもタイマーの数が増えていく場合には変数を追加していかなければならない。

そこでタイマーを変数に入れなくても止める(invalidate()する)ことにしました。

引数に自分自身を入れちゃおう

ViewController.swift
class ViewController: UIViewController {
        // 30秒後に止まるタイマー
        func setTimer() {
            Timer.scheduledTimer(timeInterval: 30, // x秒後
                                 target: self,
                                 selector: #selector(self.stopTimer(_:)), // 引数にTimer自身を指定する
                                 userInfo: nil, 
                                 repeats: false)
            print("Timer started")
        }

        @objc func stopTimer(_ timer: Timer) {
            timer.invalidate()
            print("Timer stopped")
        }
}

このようにselectorで関数を指定するときに引数を自分自身にすることで、変数にTimerのインスタンスを保持しなくてもあとで.invalidate()することができます。

おしまい

Timerはメモリを圧迫するので、不要になったら必ず.invalidate()しよう。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4