强,弱或无主参考周期与定时器
Strong, weak or unowned in reference cycle with Timer
我有一个 UIViewController
引用了一个重复调用闭包的 Timer
对象。 Timer
对象在其块中捕获 self
。据我了解,这会导致视图控制器和块之间出现 retains cycle
。有一个逻辑是把timer设置为nil然后retain cycle被打破,但是不一定会执行。
我的问题如下:只要应用程序存在,视图控制器就会存在(至少在当前实现中)。在这种情况下——我应该如何最好地处理这个保留周期?我是否应该忽略它,因为 View 控制器无论如何都不会被释放。我是否应该考虑未来可能发生的变化并使用 unowned
或 weak
参考来处理它,以及哪一个。我猜它应该是 unowned
,因为计时器仅由 View Controller 保留,一旦 View Controller 被释放,它就应该被释放,但不确定我是否遗漏了什么。先感谢您。以下代码是我正在谈论的简单示例。 Class A
是视图控制器。
class A {
var timer: Timer? = nil
var varToReference: Int = 0
func startTimer() {
timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true, block: { (theTimer) in
self.varToReference += 1
})
}
func stopTimer() {
if let theTimer = timer {
theTimer.invalidate()
timer = nil
}
}
func onAdapterStarts() {
self.startTimer()
}
func onAdapterStops(){
self.stopTimer()
}
deinit {
print("A Deinit")
}
}
在您的情况下,weak
和 unowned
是可以接受的。在计时器块中使用简单的代码,我建议使用 weak
,否则,您可以更喜欢 unowned
。使用 weak
关注您项目的未来更新和扩展。
timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true, block: {[weak self] (theTimer) in
self?.varToReference += 1
})
Retain cycle is the condition when two objects keep a reference to each other and are retained, it creates a cycle since both objects try to retain each other.
现在让我们来看看你的示例代码
在您的示例中,Class A
通过 timer
变量拥有闭包。如果您不将 self
声明为 weak
或 unowned
,闭包也会拥有 self
,从而创建一个强引用循环。
unowned
和 weak
之间的区别
unowned
和 weak
之间的一个简单区别是 weak
被声明为可选,而 unowned
则不是。通过声明它 weak
你可以处理它在某些时候可能在闭包中是 nil 的情况。如果您尝试访问恰好是 nil 的 unowned
变量,它将 使整个程序崩溃 。因此,仅当您确定变量将始终存在而闭包在
附近时才使用 unowned
Always be feature ready, as your work in any mobile app should always
be expandable.
See this accepted answer for better understanding.
我有一个 UIViewController
引用了一个重复调用闭包的 Timer
对象。 Timer
对象在其块中捕获 self
。据我了解,这会导致视图控制器和块之间出现 retains cycle
。有一个逻辑是把timer设置为nil然后retain cycle被打破,但是不一定会执行。
我的问题如下:只要应用程序存在,视图控制器就会存在(至少在当前实现中)。在这种情况下——我应该如何最好地处理这个保留周期?我是否应该忽略它,因为 View 控制器无论如何都不会被释放。我是否应该考虑未来可能发生的变化并使用 unowned
或 weak
参考来处理它,以及哪一个。我猜它应该是 unowned
,因为计时器仅由 View Controller 保留,一旦 View Controller 被释放,它就应该被释放,但不确定我是否遗漏了什么。先感谢您。以下代码是我正在谈论的简单示例。 Class A
是视图控制器。
class A {
var timer: Timer? = nil
var varToReference: Int = 0
func startTimer() {
timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true, block: { (theTimer) in
self.varToReference += 1
})
}
func stopTimer() {
if let theTimer = timer {
theTimer.invalidate()
timer = nil
}
}
func onAdapterStarts() {
self.startTimer()
}
func onAdapterStops(){
self.stopTimer()
}
deinit {
print("A Deinit")
}
}
在您的情况下,weak
和 unowned
是可以接受的。在计时器块中使用简单的代码,我建议使用 weak
,否则,您可以更喜欢 unowned
。使用 weak
关注您项目的未来更新和扩展。
timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true, block: {[weak self] (theTimer) in
self?.varToReference += 1
})
Retain cycle is the condition when two objects keep a reference to each other and are retained, it creates a cycle since both objects try to retain each other.
现在让我们来看看你的示例代码
在您的示例中,Class A
通过 timer
变量拥有闭包。如果您不将 self
声明为 weak
或 unowned
,闭包也会拥有 self
,从而创建一个强引用循环。
unowned
和 weak
之间的区别
unowned
和 weak
之间的一个简单区别是 weak
被声明为可选,而 unowned
则不是。通过声明它 weak
你可以处理它在某些时候可能在闭包中是 nil 的情况。如果您尝试访问恰好是 nil 的 unowned
变量,它将 使整个程序崩溃 。因此,仅当您确定变量将始终存在而闭包在
unowned
Always be feature ready, as your work in any mobile app should always be expandable.
See this accepted answer for better understanding.