tilt-shift photography of HTML codes

Quick Workaround: AS3 gotoAndStop Nasty Bug

Okay, I admit it. I am old-school. I use Flash Pro CS5 as my only Flash development tool. I do all my coding on timelines and I like it that way.

I have been working with AS3 for few months now, and I have to say, I have to write twice the code to actually do what I was able to do using AS2. I miss those good old days.

Anyway, I’ve been developing an AIR Mobile application and hit by this nasty gotoAndStop bug. If you are feeling lazy to click the link and see detailed explanation, here’s a excerpt from the post:

myMC.gotoAndStop('FINISHED_SCREEN');
myMC.result_txt.text = "You won!";


Leading to following error:

TypeError: Error #1009: Cannot access a property or method of a null object reference.

To clarify: in this context, result_txt is the name of a TextField that exists on the stage, and only exists on the frame with the label "FINISHED_SCREEN". If you haven’t previously displayed this frame, and you run the code above, then sometimes you will find that the result_txt TextField object hasn’t been properly instantiated by Flash yet when the second line is run – therefore myMC.result_txt will resolve to null, and you’ll get the error above.

I tried and found many kind of solutions, but they were more like adding a lot more code and changing the way my jumping from frame to frame works.

So, experimented a little, and ended up with my own solution. It’s kind of dirty one ;)

First you need to Export for ActionScript your problematic MovieClip from Library. Make sure you add text Class at the end of export ID/class name. i.e. my original Library item was named "mcCircle", so I Export it as "mcCircleClass".

Now, on the keyframe where you are getting that null reference error. Initialize your MovieClip as follows:

var mcCircle:mcCircleClass;
if(this.getChildByName("mcCircle") == null)
{
    mcCircle = new mcCircleClass();
addChild(mcCircle); }

After this you can access mcCircle as before. You might have to set it’s properties (x/y etc.) again, as we just created a new instance which doesn’t have values from previous instance. In my case, I just had to set it’s X and Y to position it back where it belonged.

It’s not as optimistic as other solutions, but it does the job when you need to quickly get through it.

I am quite disappointed by Adobe since Timelines are the basics of Flash from the very core. This bug is around since Flash 9 days, and Adobe still haven’t fixed it. Come on Adobe, you can do better!

Update: Some other references to the problem:

// chall3ng3r //

9 Comments

  1. Email me dude I have a MAJOR bitch about this same issue. Would be good to chat about it

    1. @b18269, haha, did you made your own workaround or you ended up using someone else’s?

      // chall3ng3r //

  2. When that AS tries to set the text, the text-field-instance doesn’t exist at that exact moment. Is not a bug. It works if you have that AS (myMC.result_txt.text = “You won!”;) in the ‘FINISHED_SCREEN’ key-frame… where the text-field is, right?

    1. Yes, of course. The object is on Stage, have it’s instance name set, and even for me it always works when my SWF reaches this keyframe for the first time (it’s a my apps main-menu Scene). But when I try to get back to the same frame from another Scene, the Stage objects are not properly initialized for AS3, but they remain visible. So, when I try to access any objects via AS3, it throws null object reference error.

      // chall3ng3r //

  3. Phil says:

    This is not a flash bug. The help documents state:

    “(gotoAndStop())… Brings the playhead to the specified frame of the movie clip and stops it there. This happens after all remaining actions in the frame have finished executing.

    So your playhead does not go to the next frame until all the code on that frame has completed executing. So you trying to set the value of text on a display object that is not instantiated on that current frame would indeed yield a null reference error.

  4. Thanks for your comment Phil,

    I think you didn’t understand. There is all the instances on Stage on same keyframe. On the same keyframe, I have a top Layer name Scripts, which contains the code to access the objects.

    As I mentioned, it even runs for the first time. But when I jump back from any other Scene back to this keyframe, it starts throwing error.

    If you search, you can find that this bug is encountered by many others as well. Check the one referenced link in my post.

    // chall3ng3r //

  5. I wrote the blog post linked-to above. I suppose that “bug” is in the eye of the beholder. Those of us who came from AS2 had no problems with a line of code changing the frame, and the next line of code attempting to access something on the stage at that frame. AS3 appears to have preserved all behavior of this type, until you suddenly try to do this and discover that, 1 time out of 20, you crash with a null reference error.

    That’s part of the most frustrating part: that using this “incorrect” patern actually works under many circumstances and environments, but then tends to suddenly fail without explanation.

    I also always considered it a bug because the behavior of the stage is inconsistent. For instance, when this bug happens, you can actually request “numChildren” and get, say, 1. Yet if you try to access the one and only child on the next line, it comes back null.

    Worst still is that following Adobe’s recommended workarounds for this also do not work consistently. Which destroys for me any credibility Adobe had left on this issue (which is very little after they had already said “this horribly inconvenient and inconsistent behavior is totally by design and not a bug at all!”).

    I still prefer the solution I laid out on my blog, which is to use an asynchronous method to move to the desired frame, and to pass along 1) a function to be run once the frame is fully loaded, and 2) an array of names of elements. The code will then wait until the frame and all of those named elements are really REALLY loaded, before executing the code.

    It’s a solution that uses minimal extra lines of code (simply put the post-load lines of script into an anonymous function that gets passed into this gotoAndPlayAndThen() solution). And when this bug comes up, you can fix it quickly by adding these few lines of code, or adding an element that came back null to the “list of things to wait to instantiate.” It’s still flawed – I would prefer if you didn’t have to manually maintain the list of names – but so far it seems to be foolproof, unlike Adobe’s recommended workarounds.

  6. @IQpierce, thanks for your detailed reply. Yes I agree, and also noted in my post, that my workaround is not the best one out there.

    But consider if, that stage instance is just a MovieClip which have some timeline animations, the designer would just want it to work like it would in AS2. He might just look for the simplest way to get pass this bug.

    I did some memory consumption tests as well on my approach, and so far it’s alright. Will try your workaround in some other project for sure.

    I can only hope and wish Adobe could just fix it. And make the instance objects init properly, before any AS3 code is executed.

    // chall3ng3r //

  7. thienhaflash says:

    You didn’t understanding the timeline well enough, when you call gotoAndStop / gotoAndPlay it won’t go right away, this is for performance reason. It will actually go at the end of that frame. If you want to access timeline elements wait until the event FRAME_CONSTRUCT fired or just wait until next frame.

    I got major problems with this before, it’s very frustrated, I know, but that’s because we didn’t understanding it yet.

    Hope this clarify something.

Leave a Reply to thienhaflashCancel reply