简体   繁体   English

强,弱或无主参考周期与定时器

[英]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.我是否应该考虑未来可能发生的变化并使用unownedweak引用来处理它,以及哪一个。 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.在你的情况下weakunowned是可以接受的。 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.保留循环是当两个对象保持对彼此的引用并被保留时的条件,它会创建一个循环,因为两个对象都试图相互保留。

Now let's take your example code现在让我们来看看你的示例代码

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声明为weakunowned ,则闭包也会拥有self ,从而创建一个强引用循环。

Difference between 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. unownedweak之间的一个简单区别是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.如果你试图访问一个恰好为nilunowned变量,它会导致整个程序崩溃 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM