[英]How to invalidate timer in extension in Swift
我试图在扩展中添加一个计时器属性。 代码如下
@objc public extension RCTTouchHandler {
static let kSessionTimer = "sessionTimer"
var sessionTimer: Timer {
get {
return objc_getAssociatedObject(self, RCTTouchHandler.kSessionTimer) as? Timer ?? Timer.scheduledTimer(timeInterval: RCTTouchHandler.kSessionExpiredDuration, target: self, selector: #selector(touchSessionExpiration), userInfo: nil, repeats: false)
}
set(timer) {
objc_setAssociatedObject(self, RCTTouchHandler.kSessionTimer, self, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
@objc func touchSessionExpiration() {
print("session expired")
}
deinit {
self.sessionTimer.invalidate()
}
}
然后, sessionTimer
强引用了这个 object ,同时这个 object 强保留了sessionTimer
。 为了避免保留周期和 memory 泄漏,我应该在 object 被取消初始化时使计时器无效。 但是,我在尝试使此扩展中的 deinit 函数中的计时器无效时遇到了以下错误。
Deinitializers may only be declared within a class
根据Swift 文档
扩展可以向 class 添加新的便利初始化程序,但不能向 class 添加新的指定初始化程序或取消初始化程序。 指定的初始化程序和取消初始化程序必须始终由原始 class 实现提供。
所以我想知道我应该如何在这个扩展中正确地使计时器无效?
正如您所说,您不能在扩展中实现deinit { }
。
您可以创建自己的 object 并在那里实现deinit { }
,而不是到处使用RCTTouchHandler
,而是使用自己的 object:
@objc extension RCTTouchHandler {
static let kSessionTimer = "sessionTimer"
}
public class MyTouchHandler: RCTTouchHandler {
private var timer: Timer? = nil
var sessionTimer: Timer {
get {
guard let timer = timer else {
let newTimer = Timer.scheduledTimer(timeInterval: RCTTouchHandler.kSessionExpiredDuration, target: self, selector: #selector(touchSessionExpiration), userInfo: nil, repeats: false)
self.timer = newTimer
return newTimer
}
return timer
}
set(timer) {
self.timer = timer
}
}
@objc func touchSessionExpiration() {
print("session expired")
}
deinit {
self.timer?.invalidate()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.