Reputation: 33
I built an extension to the UIButton class to do fadeOut. When I use this I get memory leak warning in the profiler. I am using Swift 4 and Xcode 9.3.
Thanks in advance for any help.
extension UIButton {
func fadeOut() {
let fadeOut = CABasicAnimation(keyPath: "opacity")
fadeOut.duration = 0.35
fadeOut.fromValue = 1
fadeOut.toValue = 0.0
fadeOut.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
fadeOut.autoreverses = false
fadeOut.repeatCount = 0
fadeOut.isRemovedOnCompletion = true
self.layer.add(fadeOut, forKey: nil)
}
}
The calling function is given below. Also please note: new, level and card are UIButtons. When I comment out button.fadeout()
in the function below the memory leak goes away as per the Xcode profiler. Hope this gives more context. If any other information is required to help analyze, I happy to provide the info.
private func menu_fadeout(){
func menu_fadeout_helper(_ button:UIButton){
button.fadeOut()
button.isHidden = true
button.isEnabled = false
}
menu_fadeout_helper(hint)
menu_fadeout_helper(new)
menu_fadeout_helper(level)
menu_fadeout_helper(card)
}
Upvotes: 1
Views: 290
Reputation: 11
Upvotes: 0
Reputation: 33
After lots of poking around it turns out the animation layers cause leaks for various reasons - most have guesses but no precise answers.
To solve my problem I reimplemented the fadeOut function without using the CABasicAnimation and using UIView.animate and made NO other change to the code. The profiler has no issues now - all is good. Thanks!
fyi there seems to inadvertent leaks whenever using stings in the context of buttons etc. If anyone has any pointers or suggestions on that topic would appreciate it.
Upvotes: 0
Reputation: 1818
After staring at the code for a couple minutes, I see the issue. In your function. . .
private func menu_fadeout(){
func menu_fadeout_helper(_ button:UIButton){
button.fadeOut()
button.isHidden = true
button.isEnabled = false
}
menu_fadeout_helper(hint)
menu_fadeout_helper(new)
menu_fadeout_helper(level)
menu_fadeout_helper(card)
}
. . .you never directly reference the UIButtons hint, new, level, and card. Eventually, after pressing the buttons a ton of times, the memory will fill up with nothing and your app will crash. (or worse)
Change the function to this to (supposedly) remove the memory leak.
private func menu_fadeout(){
func menu_fadeout_helper(_ button: UIButton) -> UIButton {
button.fadeOut()
button.isHidden = true
button.isEnabled = false
return button
}
menu_fadeout_helper(self.hint)
menu_fadeout_helper(self.new)
menu_fadeout_helper(self.level)
menu_fadeout_helper(self.card)
}
Upvotes: 0