[英]Strong, weak or unowned in reference cycle with Timer
I have a UIViewController
that has a reference to a Timer
object that is calling a closure repeatedly.我有一个
UIViewController
,它引用了一个重复调用闭包的Timer
对象。 The Timer
object captures self
in its block. Timer
对象在其块中捕获self
。 As far as I understand this leads to a retains cycle
between the View Controller and the block.据我了解,这会导致视图控制器和块之间的
retains cycle
。 There is a logic to set the timer to nil and then the retain cycle is broken, but it may not be executed.有一个逻辑是把timer设置为nil然后retain cycle被打破,但是不一定会执行。
My question is the following: The View Controller will live as long as the app lives (at least in current implementation).我的问题如下:只要应用程序存在,视图控制器就会存在(至少在当前实现中)。 In this case - how should I best take care of this retain cycle?
在这种情况下——我应该如何最好地处理这个保留周期? Should I ignore it since the View controller won't be released anyway.
我是否应该忽略它,因为 View 控制器无论如何都不会被释放。 Should I consider possible future changes and handle it with
unowned
or weak
references and which one.我是否应该考虑未来可能发生的变化并使用
unowned
或weak
引用来处理它,以及哪一个。 I guess it should be unowned
since the timer is retained only by the View Controller and it should be released once the View Controller is released, but not sure if I am missing something.我想它应该是
unowned
的,因为计时器仅由 View Controller 保留,一旦 View Controller 被释放,它就应该被释放,但不确定我是否遗漏了什么。 Thank you in advance.先感谢您。 The following code is simple example of what I am talking about.
以下代码是我正在谈论的简单示例。
Class A
is the 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")
}
}
In your case weak
and unowned
are acceptable.在你的情况下
weak
和unowned
是可以接受的。 With simple code inside of timer block i suggest to use weak
, otherwice, you can prefer unowned
.在计时器块内使用简单代码,我建议使用
weak
,否则,您可以更喜欢unowned
。 Use weak
to care about future updates and extendings of your project.使用
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.
保留循环是当两个对象保持对彼此的引用并被保留时的条件,它会创建一个循环,因为两个对象都试图相互保留。
In your example, Class A
owns the closure through the timer
variable.在您的示例中,
Class A
通过timer
变量拥有闭包。 If you do not declare self
as weak
or unowned
the closure would also own self
creating a strong reference cycle.如果您不将
self
声明为weak
或unowned
,则闭包也会拥有self
,从而创建一个强引用循环。
unowned
and weak
unowned
weak
的区别A simple difference is between unowned
and weak
is that weak
is declared as optional where as unowned
is not. unowned
和weak
之间的一个简单区别是weak
被声明为可选的,而 as unowned
则不是。 By declaring it weak
you get to handle the case that it might be nil inside the closure at some point.通过声明它
weak
你可以处理它在某些时候可能在闭包内为nil的情况。 If you try to access an unowned
variable that happens to be nil , it will crash the whole program.如果你试图访问一个恰好为nil的
unowned
变量,它会导致整个程序崩溃。 So only use unowned
when you are positive that variable will always be around while the closure is around因此,仅当您确定变量在闭包周围时始终存在时才使用
unowned
Always be feature ready, as your work in any mobile app should always be expandable.
始终准备好功能,因为您在任何移动应用程序中的工作都应该始终是可扩展的。
See this accepted answer for better understanding. 请参阅此已接受的答案以获得更好的理解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.