如何在 RxSwift 中使用 interval 取代 Timer?

Timer 是一個很常使用的工具,我常常用他來做重複的事情,比如說時間的倒數計時器。對於已經習慣 RxSwift 的我來說,總是希望能夠將程式盡量使用 RxSwift。而 RxSwift 也有類似 Timer 的工具喔,非常好用喔。

swift 1

只要用下列的方式創造 Timer 就好了,而這個 Timer 會每秒執行一次。如果要改變執行的頻率,就要改變設定「.seconds(1) 」。

let timer = Observable<Int>
        .interval(.seconds(1), scheduler:MainScheduler.instance)
        .subscribe(onNext: { [weak self] value in
            print("hi, I'm Timer")
        }, onCompleted: {
        })

而上面的 Timer 是在主執行緒跑,如果我們同時有好幾個 Timer,那麼 CPU  一定達到 100%,所以我們可以指定在背景跑。

let timer = Observable<Int>
           .interval(.seconds(1), scheduler:ConcurrentDispatchQueueScheduler(qos: .background))
           .subscribe(onNext: { [weak self] value in
               print("hi, I'm Timer")
           }, onCompleted: {
           })

如果要停止 Timer,只要用一個簡單的函式就可以了。

let timer = Observable<Int>
           .interval(.seconds(1), scheduler:ConcurrentDispatchQueueScheduler(qos: .background))
           .subscribe(onNext: { [weak self] value in
               print("hi, I'm Timer")
           }, onCompleted: {
           })

/// 停止 Timer
timer.dispose()

如果要停止 Timer,只要用一個簡單的函式就可以了。

let timer = Observable<Int>
           .interval(.seconds(1), scheduler:ConcurrentDispatchQueueScheduler(qos: .background))
           .subscribe(onNext: { [weak self] value in
               print("hi, I'm Timer")
           }, onCompleted: {
           })

/// 停止 Timer
timer.dispose()

Timer 在畫面消失或物件 deinit 時一定要停止!

deinit {
    timer.dispose()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(_: animated)
    timer.dispose()
}

結合一下程式碼

 let timer = Observable<Int>
           .interval(.seconds(1), scheduler:ConcurrentDispatchQueueScheduler(qos: .background))
           .subscribe(onNext: { [weak self] value in
               self?.queue.async(execute: { in
                    DispatchQueue.main.sync(execute: {
                        self?.tableview?.reloadData()
                    })
                })
           }, onCompleted: {
           })

或者,你可以使用 RxSwift 的 observe 函式,這樣也可以達到異曲同工之妙。

let timer = Observable<Int>
        .interval(.seconds(1), scheduler: ConcurrentDispatchQueueScheduler(qos: .background))
        .observe(on: MainScheduler.instance)
        .subscribe(onNext: { [weak self] value in
            self?.tableview?.reloadData()
        }, onCompleted: {
        })
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments