如何在 Swift 中使扩展中的计时器无效
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
对该对象有强引用,同时,该对象强保留sessionTimer
。为了避免保留周期和内存泄漏,我应该在对象被取消初始化时使计时器无效。但是,我在尝试使此扩展中的 deinit 函数中的计时器无效时遇到以下错误。
Deinitializers may only be declared within a class
Extensions can add new convenience initializers to a class, but they cannot add new designated initializers or deinitializers to a class. Designated initializers and deinitializers must always be provided by the original class implementation.
所以我想知道我应该如何在此扩展程序中正确地使计时器失效?
如您所说,您无法在扩展中实现 deinit { }
。
您可以创建自己的对象并在那里实现 deinit { }
而不是到处使用 RCTTouchHandler
,而是使用您自己的对象:
@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()
}
}
我试图在扩展程序中添加计时器 属性。代码如下
@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
对该对象有强引用,同时,该对象强保留sessionTimer
。为了避免保留周期和内存泄漏,我应该在对象被取消初始化时使计时器无效。但是,我在尝试使此扩展中的 deinit 函数中的计时器无效时遇到以下错误。
Deinitializers may only be declared within a class
Extensions can add new convenience initializers to a class, but they cannot add new designated initializers or deinitializers to a class. Designated initializers and deinitializers must always be provided by the original class implementation.
所以我想知道我应该如何在此扩展程序中正确地使计时器失效?
如您所说,您无法在扩展中实现 deinit { }
。
您可以创建自己的对象并在那里实现 deinit { }
而不是到处使用 RCTTouchHandler
,而是使用您自己的对象:
@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()
}
}