定時器NSTimer用法

創建一個NSTimer,有多種方法,如

scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
timerWithTimeInterval:target:selector:userInfo:repeats:

等等
其中,用不帶有scheduled的,在初始化了后,還需要調用
addTimer:forMode:方法,將Timer加入到runloop中。


參數:

  1. seconds定時時間
  2. target發送對象
  3. aSelector定時器啟動調用的方法
  4. userInfo可為nil,使用者的信息
  5. repeats定時器是否循環

在Timer添加到runloop后,定時器立刻啟動,在seconds時間后,調用aSelector方法,如果最開始時不想等seconds時間,可調用-fire方法,立刻調用aSelector方法。


-invalidate方法可使定時器失效。

注意:

  • 使用-invalidate方法后,即使再次使用-fire方法也不會讓定時器再次工作,因為-invalidate方法是使Timer失效。
  • 暫停定時器:可使用[self setFireDate:[NSDate distantFuture]];方法:即將定時器啟動時間設為無窮遠
    恢復定時器,使用[self setFireDate:[NSDate date]];方法:即將定時器啟動時間設為現在的時刻。
  • 對于需要在暫停時刻改變定時時間間隔的情況,則需要重新創建NSTImer,啟動,通過-invalidate停止定時器。

NSTimer 內存泄漏解決方法

由于 NSTimer 容易與持有它的對象互相引用,從而導致內存泄漏,因此在使用時需要格外注意。 iOS 10.0 以后已經有了 scheduledTimer(withTimeInterval:repeats:block:) 方法解決內存泄漏問題,但是 iOS 10.0 以前還需要自己想辦法。

  1. 如果 timerWithTimeInterval:target:selector:userInfo:repeats: 中傳給 target 的為 weakSelf 是否可以?
    不可以。因為 Timer 對 target 強引用,強引用一個 weak 變量,對變量所指的對象仍然是強引用
  2. 借鑒參考 1 中第 52 條的方法解決該問題。
extension Timer {
    class func njyScheduledTimer(timerInterval: TimeInterval, block: @escaping () -> Void, repeats: Bool) -> Timer {
        return Timer.scheduledTimer(timeInterval: timerInterval, target: self, selector: #selector(njyBlockInvoke(timer:)), userInfo: [block copy], repeats: repeats)
    }

    @objc class func njyBlockInvoke(timer: Timer) {
        let block = timer.userInfo as? () -> Void
        if let block = block {
            block()
        }
    }
}

注意:在實際使用時,仍然要注意內存泄漏的問題,因此需要使用 weak var weakSelf = selflet strongSelf = weakSelf 打破保留環,解決內存泄漏的問題。

參考

  1. Effective Objective-C 2.0
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容