简体   繁体   中英

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. The Timer object captures self in its block. As far as I understand this leads to a retains cycle between the View Controller and the block. There is a logic to set the timer to nil and then the retain cycle is broken, but it may not be executed.

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. Should I consider possible future changes and handle it with unowned or weak references and which one. 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. Thank you in advance. The following code is simple example of what I am talking about. Class A is the View Controller.

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. With simple code inside of timer block i suggest to use weak , otherwice, you can prefer unowned . Use weak to care about future updates and extendings of your project.

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. If you do not declare self as weak or unowned the closure would also own self creating a strong reference cycle.

Difference between unowned and weak

A simple difference is between unowned and weak is that weak is declared as optional where as unowned is not. By declaring it weak you get to handle the case that it might be nil inside the closure at some point. If you try to access an unowned variable that happens to be nil , it will crash the whole program. So only use unowned when you are positive that variable will always be around while the closure is around

Always be feature ready, as your work in any mobile app should always be expandable.

See this accepted answer for better understanding.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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