如果定時器重複執行,只要目標位於內存中,它就不會失效。
對我來說,最好的解決方案是使用這個類 - 它將觀察目標,並且它的目標是釋放它會使自己失效。
final class WeakTimer {
private weak var timer: Timer?
private weak var target: AnyObject?
private let action: (Timer) -> Void
private init(timeInterval: TimeInterval,
target: AnyObject,
repeats: Bool,
userInfo: Any?,
action: @escaping (Timer) -> Void) {
self.target = target
self.action = action
self.timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(fire(timer:)), userInfo: userInfo, repeats: repeats)
RunLoop.main.add(self.timer!, forMode: .commonModes)
}
class func scheduledTimer(timeInterval: TimeInterval,
target: AnyObject,
userInfo: Any?,
repeats: Bool,
action: @escaping (Timer) -> Void) -> Timer {
return WeakTimer(timeInterval: timeInterval,
target: target,
repeats: repeats,
userInfo: userInfo,
action: action).timer!
}
@objc fileprivate func fire(timer: Timer) {
if target != nil {
action(timer)
} else {
timer.invalidate()
}
}
}
感謝解釋。你能鏈接關於這個的任何官方文檔嗎? –
您可以在這裏閱讀: https://developer.apple.com/reference/foundation/timer 「運行循環保持對其計時器的強烈參考」。這很好解釋它。 –
根據文檔'= nil'不是nesseccery,因爲'使計時器無效立即禁用它,以便它不再影響運行循環。運行循環然後在invalidate()方法返回之前或稍後的點處移除定時器(以及它對定時器的強引用)。 –