PDA

Просмотр полной версии : Классы и LoadMovieClip


the_scratch
30.01.2009, 12:59
AS2, MX2004

Приветствую всех.

У меня очередные проблемы с Flash, у меня они постоянно возникают, причём неразрешимые какие-то. На этот раз всё упёрлось в объём памяти.

Ситуация такая... Есть Swf, внутри у него (в библиотеке) лежат "символы", которые MovieClip. В них пофреймово хранятся картинки, такие типа мультики. Мувиков несколько штук, каждый в ActionScript экспортируется в виде одного и того же класса, пронаследованного от MovieClip.

Мувики показываются по желанию пользователя, между ними можно свободно переключатся. Оказывается, что показ такого мувика отъедает некоторое количество памяти, которая назад не отдаётся никогда.

На РС никаких проблем. Мувики показываются, память какое-то время отъедается, отъедается, потом, когда уже все картинки показаны хотя бы раз (это я так восстанавливаю картину происходящего по собственному разумению), процесс отъедания памяти останавливается, и дальше мувики показываются, а память уже не требуется. Ну увеличился объем ролика в памяти от 20 до 80 М, фигня какая. К слову, сам SWF вообще-то 5М, я изначально конкретно так парился насчёт размеров и старался всё минимизировать.

Потому что вот на КПК памяти всего 40 М. Ну и соответственно, в какой-то момент система наглухо завешивается. Наглухо.

Попытки использовать System.gc() ни к чему не привели. GC чистит совсем другую память, не ту, которая отводится под картинки и мувики. Все new-delet'ы я проверил, в принципе, проблема не в их. Память совершенно очевидно отъедается именно при показе картинок, которые ещё не показывались, это факт.

Как я сейчас вижу решение? Хочу попробовать мувики-мультики хранить не в библиотеке внутри swf, а в виде отдельных файлов swf, и подгружать их через loadMovie, а не attachMovie, как сейчас. Это вообще-то ужасно, потому что возникнут очевидные лаги при переключении мультиков и вообще вся изначальная проработанная концепция идёт к... Но мне хоть как-то надо разруливать ситуацию с памятью... Есть просто надежда, что unloadMovie вызовет хоть какую-то зачистку памяти от уже показанных изображений.

Собственно, Вопрос. Мувики внутри библиотеки у меня ассоциированы с классом. А как их ассоциировать с классом при хранении снаружи SWF? Код класса где должен быть? Помогите. пожалуйста, разобраться.

iNils
30.01.2009, 13:03
Какой System.gc() в AS2?

the_scratch
30.01.2009, 13:12
Не знаю, какой. Я сделал на таймлайне System.gc, синтакс-чекер заругался. Добавил import flash.system, всё заработало. Делает ли он зачистку или нет, мне неведомо, но по косвенным данным, делает. У меня сначала шла небольшая утечка памяти***, с использованием System.gc() она прекратилась. Это не отменило проблем с памятью под картинки, естественно, иначе я бы не задавал тогда глупых вопросов.

___
*** это не совсем правильный термин, в данном случае. Не утечка, а планомерное расходование, что ли. Я так подозреваю, что в какой-то момент GC эту память всё-таки должен чистить, просто без форсирования зачистки процесс освобождения идёт не часто, а довольно редко, хоть и периодически.

iNils
30.01.2009, 13:16
1. System.gc - есть только в AS3.
2. System.gc - работает только в отладочных версиях плеера (отладочные версии плеера нужны только для AS3).

the_scratch
30.01.2009, 13:19
В любом случае, System.gc() ситуацию мне не поправит никак.
С классами-то чего делать? :-)

iNils
30.01.2009, 14:01
А removeMovieClip используете?

the_scratch
30.01.2009, 14:23
Сейчас - не использую. Все мувики-мультики одновременно существуют в памяти, но показывается только один из них. Не было смысла их удалять - зачем. если на них в любой момент может произойти переключение?

Сейчас (видимо) при переключения с одного мувика на другой мне придётся делать одному loadMovie, а другому removeMovieClip. Но пока я не пойму, как ассоциировать класс с подгружаемым мувиком (или наоборот, мувик с классом), я не продвинусь.

Вы имеете в виду, что стоит делать не loadMovie, а всё тот же attachMovie, но с одновременным removeMovieClip для того клипа, что выбывает из показа?

iNils
30.01.2009, 14:31
Вы создали объект и если даже его прячете, он все равно существует в памяти. Конечно у вас будет память расходоваться.

the_scratch
30.01.2009, 14:44
Я это всё прекрасно понимаю. Проблема в другом. я же написал.
Или я непонятно как-то изъясняюсь?

iNils
30.01.2009, 14:48
Вы написали, что у вас не чиститься память. Так?

the_scratch
30.01.2009, 15:03
Собственно, Вопрос. Мувики внутри библиотеки у меня ассоциированы с классом. А как их ассоциировать с классом при хранении снаружи SWF? Код класса где должен быть? Помогите. пожалуйста, разобраться.

А с тем, что память не чистится, ничего не сделать. Пока мувики не отгружены через removeMovieClip, память (занятую плеером под какие-то нужды для каждой картинки отдельно) так и будет занятой. Причём, насколько я понял из чтения интернетов, это касается и всё того же system.gc() из AS3.

Я повторю. Не факт, но есть надежда, что removeMovieClip (unloadMovie) освободит память, занятую картинками. Но возникает проблема: подгружаемый снаружи мувик должен быть чётко связан с определённым классом. Как это сделать, я не понимаю.

iNils
30.01.2009, 15:20
Мувики показываются, память какое-то время отъедается, отъедается, потом, когда уже все картинки показаны хотя бы раз
...
Как я сейчас вижу решение? Хочу попробовать мувики-мультики хранить не в библиотеке внутри swf, а в виде отдельных файлов swf, и подгружать их через loadMovie, а не attachMovie, как сейчас
Вы сначала связку attachMovie - removeMovieClip попробуйте.

the_scratch
30.01.2009, 15:51
Связка attachMovie - removeMovieClip не работает.
Память не отдаётся.

Вообще-то, я это ещё утром пробовал.
По-моему, всё дело в том, что мувик по-прежнему в памяти - конкретно "в библиотеке".
Нужны отгружаемые/подгружаемые, внешние swf.

Вопрос, заданный в первом посте - как увязать подгружаемый мувик с конкретным классом?
Это во флеше вообще реально сделать? Без привязки к моей задаче? Можно или нет?

dimarik
30.01.2009, 18:25
Можно. Определите классы в главном мувике. Для этого заставьте компилятор вкомпилить эти классы путем указания в первом (или нужном) кадре

import AClass;
AClass;

При желани проверьте декомпилятором.

the_scratch
02.02.2009, 15:42
Я извиняюсь, а дальше?

Главный мувик будет знать про мой класс. Но если я делаю loadMovie, то подгруженный мувик не имеет никакого класса, он просто мувик, и всё. Просто мувик. Класса MovieClip. Как сделать, чтобы он был (стал) моим классом?

loadMovie(url:String,target:Object [, method:String]) : Void

target Ссылка на мувиклип или строковое представление пути к мувиклипу, в который будет производиться загрузка. Содержимое мувиклипа, в который происходит загрузка, будет замещено загруженным SWF файлом или изображением.

Если я сделаю так:
var mc : MyClass = new MyClass();
loadMovie("file:///...", mc);
то mc, насколько я понял из описания, вообще забудет всё и вся.
Даже то, что он класса MyClass, -- и то забудет.
Или нет?

dimarik
02.02.2009, 18:26
что-то типа этого:
// File main.swf
import AClass;

var aClassInstance:AClass;

var mcl:MovieClipLoader = new MovieClipLoader();
this.mcl.addListener(this);
this.mcl.loadClip('external.swf');

this.onLoadInit = function(target:MovieClip) {
this.mcl.removeListener(this);
delete this.mcl;
this.aClassInstance = AClass.assign(target);
trace( this.aClassInstance.isAlive() );
}


//-----------------------------
// File AClass.as
//-----------------------------

class AClass {

public static function assign(mc:MovieClip):AClass {
if (!mc) return null;
var c:Function = AClass;
mc.__proto__ = c.prototype;
c.call(mc);
return AClass(mc);
}

/**
* Constructor.
*/
private function AClass() {
super();
trace("AClass constructor");
}

public function isAlive():String {
return 'Yheee, I am real alive!';
}
}

Что-то такое есть у silin'a (http://silin.fatal.ru/#AS2/manager).

the_scratch
04.02.2009, 13:30
dimarik, спасибо. Я понял, опробовал, вроде работает.
Пока ещё не переписывал код, но кажется, всё получится и с размерами победим.