Во-первых, позвольте мне извиниться за то, что я сосредоточился только на стороннем аспекте этого вопроса (в моих комментариях к ответу Феномаса); хотя я уже высказал свою точку зрения и даже согласен с тем, что объектная ориентация или, по крайней мере, формальный синтаксис класса был добавлен в AS1 в качестве запоздалой мысли под названием AS2 - и в некоторых моментах, как он показывает - я пренебрег ответом на ваш реальный вопрос .
Перечитывая эту ветку, я думаю, что все сводится к "ожиданию одного кадра". Это обходной путь, который мне приходилось использовать много-много раз в AS2, поэтому мне кажется странным, что я не заметил, что это было настоящей проблемой здесь.
В любом случае, ваш обходной путь, вероятно, сработает, но, как вы говорите, он может стать кошмаром для техобслуживания очень быстро. Опция Fenomas является еще одним допустимым решением. В этом случае я бы не пошел таким путем, если бы мог избежать этого, но не из-за производительности; скорее, потому что перестановка многих вещей, когда вы уже выложили вещи, может быть большой работой.
Итак, возможно, вы могли бы попробовать что-то действительно простое, как:
mc.gotoAndPlay("on");
this.onEnterFrame = function():Void {
trace(mc.inst instanceof C);
delete this.onEnterFrame;
};
И я думаю, что это должно работать. Событие enterFrame будет перехвачено вашим обработчиком через один кадр после регистрации в нем. В этот момент у вас есть готовый фрейм, поэтому вам нужно просто очистить обработчик и сделать то, что вы обычно делаете, сразу после выпуска gotoAndPlay.
Я помню, что когда-то мне приходилось делать что-то очень похожее (это был не совсем тот же сценарий, но он сводился к ожиданию одного кадра), поэтому в то время я написал очень простой класс для централизации этого кода. Это было что-то вроде этого:
class FrameDelay {
function FrameDelay(scope:Object,callback:Function,args:Array) {
// get a reference to the current enterFrame handler
// (if any), so we can restore it back when we're done
var oldEnterFrameHandler:Function = _root.onEnterFrame;
_root.onEnterFrame = function():Void {
oldEnterFrameHandler();
callback.apply(scope,args);
_root.onEnterFrame = oldEnterFrameHandler;
}
}
}
И вы бы использовали это так:
mc.gotoAndPlay("on");
new FrameDelay(this,onFrameReady,["a","1"]);
function onFrameReady():Void {
// arguments (if any), will be available in the arguments array
trace(arguments.length);
trace(mc.inst instanceof C);
trace(this);
}
Вы передаете область видимости, функцию и, необязательно, массив аргументов. Скорее всего, они вам не понадобятся, и можно было бы просто сделать так, чтобы конструктор класса принял обратный вызов. Но в некоторых случаях у вас могут быть проблемы с областью при обратном вызове (это проблема AS2), поэтому передача области явно более безопасна.
Также обратите внимание, что я использую _root.onEnterFrame. Хотя я делаю «резервную копию» исходного обработчика и восстанавливаю его обратно, когда я закончу, это не обязательно означает, что другие части кода являются такими вежливыми (!). Таким образом, обработчик может быть перезаписан. Если вы думаете, что это может быть проблемой, возможно, вы можете динамически создать мувиклип в корне на некоторой глубине, которую вы знаете, что он не используется, и заменить _root.onEnterFrame на _root.dummy_mc.onEnterFrame.
В любом случае, имейте в виду, что простой встроенный onEnterFrame сделает эту работу, поэтому, возможно, вам даже не понадобится использовать класс для этого.