-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CRITICAL: MemoryLeak : Kinetic doesn't release target on complete, prevents deinit #15
Comments
The engine does store a strong reference to each target so it can cache Tween instances associated with it for returning later via |
I prefer the second one, too. I guess the vast majority of calls are one offs. Or if someone stores the return value and tries to trigger the play handle after the animation has finished? I have no problem if that's explicitly not possible as long as it is mentioned in the docs. |
I opted for the automatic approach for removing tweens from the cache when they have completed their animation, which is in this commit if you want to review: 5ed0e31 I verified that the tweens are removed from the internal cache by calling If the tween is part of a timeline, the timeline instance always retains the child tweens, so there's no need to manually store a reference to a tween within a timeline. However, if you want to be able to replay a single Tween instance that's not part of a Timeline, a strong reference will be needed since the object will be deallocated when removed from the internal cache when completed. |
Great! Good solve! |
hmmm, there is still an issue.
I made a function to be called before the view disappears, to call |
@markuswinkler Can you provide more code on how you're implementing this animation where you're noticing the issue? Looks like you're adding the animation code directly within a UIView subclass ( I did a test locally trying to reproduce how you have your animation setup and didn't notice any memory leaks. Here's my simple UIView subclass where the animation is setup: class TestView: UIView {
var timeline = Timeline()
func animate() {
timeline.add(Kinetic.fromTo(self, duration: 0.5, from:[.Translate(0, bounds.height)], to:[.Translate(0,0)]).ease(Easing.outSine),position: 0)
timeline.play()
}
func reset() {
timeline.kill()
}
} And the simple view lifecycle methods in the controller, where override func viewDidLoad() {
super.viewDidLoad()
testView = TestView(frame: CGRect(origin: CGPoint(x: 100, y: 200), size: CGSize(width: 100, height: 100)))
testView.backgroundColor = UIColor.greenColor()
view.addSubview(testView)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
testView.animate()
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
testView.reset()
} |
Just ran your test, can confirm it works now.
and
deinit is called when the animation finishes. When I posted the bug initially deinit wasn't called after completion. |
Sweet, I like those kind of issues. :) |
This one was very hard to track down.
I have a
Kinetic.from( ... )
animation in aUIViewControllerAnimatedTransitioning
class.Although the
deinit
method of the class is called at the end, Kinetic still keeps a reference to the animated view, preventing it from deinit.If I call
Kinetic.killTweensOf(playerVC.playerView)
at the end of the class it works and the target removes itself from memory.Probable workaround could be a
.autoKill().
chain element.The text was updated successfully, but these errors were encountered: