Why use 'unowned' in UIViewPropertyAnimator

875 views Asked by At

So ive been doing some reading about UIViewPropertyAnimator and in the examples I've been looking at, they do something like this:

animator = UIViewPropertyAnimator(duration: 2.0, curve: .easeInOut, animations: { 
        [unowned self, redBox] in
        redBox.center.x = self.view.frame.width
        redBox.transform = CGAffineTransform(rotationAngle: CGFloat.pi).scaledBy(x: 0.001, y: 0.001)
    })

I dont understand the '[unowned self, redBox] in' part of it. Can anyone explain what we use it for?

I know that unowned is usually used to decide how the reference count is determined and that it can not be set to nil as the references are going to not exist one without the other(as an alternative to weak), but i dont understand the use here, and I dont understand the bracket part. It looks to me to be an array of the item im animating and the view its located in?

Full code is as follows:

import UIKit

class ViewController: UIViewController {

    var animator: UIViewPropertyAnimator!

    override func viewDidLoad() {
        super.viewDidLoad()

        //redBox

        let redBox = UIView(frame: CGRect(x: 10, y: 100, width: 100, height: 100))
        redBox.translatesAutoresizingMaskIntoConstraints = false// lar oss redigere posisjon og sånn selv, uten at xcode setter posisjon/størrelse i stein.
        redBox.backgroundColor = .red
        redBox.center.y = view.center.y

        view.addSubview(redBox)

        animator = UIViewPropertyAnimator(duration: 2.0, curve: .easeInOut, animations: { 
            [unowned self, redBox] in
            redBox.center.x = self.view.frame.width
            redBox.transform = CGAffineTransform(rotationAngle: CGFloat.pi).scaledBy(x: 0.001, y: 0.001)
        })

        // slider

        let slider = UISlider()
        slider.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(slider)
        slider.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        slider.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
        slider.addTarget(self, action: #selector(sliderChanged), for: .valueChanged)

    }
    func sliderChanged(_ sender: UISlider){
        animator.fractionComplete = CGFloat(sender.value)
    }

}
1

There are 1 answers

2
Sulthan On BEST ANSWER
  1. We need to use either weak or unowned otherwise an ownership (reference) cycle would be created (self => animator => animations => self).

  2. We can use unowned instead of weak because we can be sure that self and animator are destroyed together and when self is deallocated, the animations won't be running any more.