I'm a little confused regarding Swift memory management. I understand that removeFromSuperview
releases the view and makes it eligible for garbage collection if retainCount
is 0. However, after tracking CFGetRetainCount(myView)
, I'm not sure how retainCount
is computed and how to properly ensure that the view will be fully released after removeFromSuperview is called.
This is what I'm getting for a simple UILabel. Code:
let myLabel = UILabel()
print("After creation")
print(CFGetRetainCount(myLabel))
myLabel.frame = CGRect(x: 0, y: 0, width: view.frame.width - 40, height: 60)
print("After frame set")
print(CFGetRetainCount(myLabel))
myLabel.text = "Lorem ipsum"
myMainView.addSubview(myLabel)
print("After added to superview")
print(CFGetRetainCount(myLabel))
let otherLabel = UILabel()
otherLabel.frame = CGRect(x: 0, y: myLabel.frame.maxY + 20, width: view.frame.width - 100, height: 60)
print("After referenced to position other view")
print(CFGetRetainCount(myLabel))
myLabel.removeFromSuperview()
print("After removed from superview")
print(CFGetRetainCount(myLabel))
Console:
After creation
3
After frame set
3
After added to superview
4
After referenced to position other view
4
After removed from superview
3
That leads me to several questions:
1) I understand CFGetRetainCount includes weak references, but how is it 3 after I just created the UILabel?
2) I'm adding views inside a function with no class-wide reference when I don't need them later (I may add gestureRecognizers too) and remove them before removing the containing view with:
myMainView.subviews.forEach({
$0.removeFromSuperview()
})
Is that considered good practice? Do gestureRecognizers prevent memory to be freed?
3) How to make sure memory is freed when the count is already at 3 when I create the view?
What am I missing?