I’ve just noticed a minor bug with TweenMax (and, I presume, TweenLite).
I set up a tween using TweenMax, and set an “onComplete” method. Then, after compiling, I noticed that there my method was throwing an NPE. However, instead of just throwing the exception once, it continued throwing it again and again: presumably, every frame. I presume the exception is stopping TweenLite (and therefore Max) in its tracks, and the tween is never removed.
Here is an excerpt from TweenLite (lines 407-410 in the version I have, 6.22) that I think is causing the problem:
if (this.vars.onComplete != null) {
this.vars.onComplete.apply(this.vars.onCompleteScope, this.vars.onCompleteParams);
}
removeTween(this);
Here’s the relevent parts of the stack trace:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at au.com.cfour.websites.c42008.view.pages.work::ProjectView/::handleExitTweenComplete()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at gs::TweenLite/complete()
(I got this same stack trace in my output panel hundreds of times before killing the SWF.)
I would suggest this simple fix:
try {
if (this.vars.onComplete != null) {
this.vars.onComplete.apply(this.vars.onCompleteScope, this.vars.onCompleteParams);
}
}
finally {
removeTween(this);
}
Should do the trick.


Joshua, this actually isn’t a bug with TweenLite/TweenMax. What appears to be happening is your handleExitTweenComplete() function has an error in it. Your try/finally addition would reduce the amount of complaining from Flash, but it wouldn’t actually fix the error in your function.
I’ve avoided try/finally additions like this for 2 reasons:
1) SPEED. According to Flash Player engineers (I literally heard it straight from their mouths), they’re bad news performance-wise. One of the primary objectives with TweenLite/TweenMax was speed and efficiency.
2) SLOP GUARD. They tend to be band-aids that cover up poor coding practices (not always). When a lot of developers moved from “tolerant” AS2 to “strict” AS3, it was frustrating to get so many errors and deal with making sure variables existed, they were typed properly, etc. but in the end, I think we all realized it was good for us. The strictness exposed weaknesses in our practices and forced us to do a better job. I could add a lot of try/finally and other checks in my code to guard against sloppy coding, but it would hurt performance and bloat the file size and ultimately enable poor coding practices. The tradeoffs don’t seem worthwhile to me.
I’d be happy to take a peek at your FLA to help you troubleshoot, Joshua. I’d encourage anyone who thinks they ran into a TweenLite/TweenMax bug to contact me first and give me the chance to look into it. There are also forums devoted to supporting the GreenSock classes at http://forums.greensock.com.
Cheers
Thanks for taking the time to reply, Jack.
No need to troubleshoot, I fixed the error immediately, before I posted in fact. And of course, the error was in the onComplete function: I said as much in my post. The reason I see this as a bug is that you are assuming that the static method removeTween() is called; not a good assumption because the onComplete method is external.
Re band-aiding. Agreed as a general point, but my suggested fix is not a band-aid (the strict typing issue seems a tangent; as I said, the exception was an NPE). It would be a band-aid if it was a try/catch rather than a try/finally; that would interfere with the flow. Finally does not do anything with the exception - it lets it pass up the call stack just as it would without the try clause - but it does ensure that whatever happens in the apply’d method (onComplete) cannot prevent removeTween() from being called.
If try/finally blocks adversely impact performance, you could consider moving the call to removeTween() to the top of the complete() method. The GC won’t kick in until at least the end of the method.
Re reporting bugs to owners first - please don’t take this post as a criticism. Everyone’s code has bugs sometimes! Remember: with enough pairs of eyes, all bugs are shallow. I enjoy using TweenMax and wouldn’t have bothered commenting on it unless I thought it deserved my notice and critique.
Good idea about moving removeTween() up a few lines. I went ahead and did that and posted a new version (6.24). Thanks for the suggestion.
I’m still not sure it’s fair to call it a “bug” since the offending code that broke things didn’t have to do with TweenLite/TweenMax and tweening functionality wasn’t impacted by the old code, but I guess the headline grabs people’s attention :-) Either way, we ended up in a better spot, and your suggestion made the class better, so thanks.
Ha ha yes, I am an attention whore! I never let the facts get in the way of a good headline :)
I’m glad you found my suggestion useful. Open source is a wonderful thing!
Keep up the good work with TweenMax. I’ve found it very useful. The website I’m just putting the finishing touches on uses it extensively along with Papervision3D …
Jack is extraordinarily helpful and he’s passionate about his code. He’s always been immediately responsive with me and I’m a huge supporter of his tweening classes (I distribute them with Gaia). If you don’t have his email, get it and you’ll get responses to any issues or questions you have. :)
1. yes, try/catch is slower
2. yes, that’s issue happen when your code have error while use tween function
3. no, not a bug just annoying sometime ;)
4. yes, i love/use TweenMax, also Gaia ;D