The idea of the code here is to remove a view (self.mv
) when it has been animated out of screen by a UIDynamicAnimator
.
The code below is based on examples from chapter 4 of the book Programming iOS 12 by Matt Neuburg. The author says both the behavior and the view (self.mv
in the code) won't be de-allocated. But he didn't elaborate extensively on this.
My questions are:
Who still retains the behavior after
self.anim.removeAllBehaviors()
?Who still retains
self.mv
?
I used Instruments, but I don't quite understand the output. Does it mean the animator retains it? But there are only green checkmarks.
With the "Debug Memory Graph" tool in XCode, I saw UIGravityBehavior
is still retained by the animator even after self.anim.removeAllBehaviors()
is called.
class MyView : UIView {
deinit {
print("dddddddd")
}
}
class ViewController: UIViewController {
var anim : UIDynamicAnimator!
weak var mv : MyView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let v = MyView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
v.backgroundColor = .red
self.view.addSubview(v)
self.mv = v
let grav = UIGravityBehavior()
self.anim = UIDynamicAnimator(referenceView: self.view)
self.anim.addBehavior(grav)
grav.action = {
let items = self.anim.views(in: self.view.bounds)
let idx = items.firstIndex(of: self.mv!)
if idx == nil {
self.anim.removeAllBehaviors()
self.mv!.removeFromSuperview()
// self.anim = nil // without this, the `MyView` is not deallocated.
}
}
grav.addItem(v)
}
}