Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Обновление экземпляра класса (http://www.flasher.ru/forum/showthread.php?t=198234)

pomuс 22.04.2013 18:32

Обновление экземпляра класса
 
День добрый

Совсем запутался в обновлении экземпляров в моем проекте, а именно:
У меня много объектов, которым передается XML данные, и на основе класса Settings выбирается, какие атрибуты будут читаться, в том числе и какой язык.

Так вот есть функция смены языка, и вот тут самая загвоздка, что много где это работает криво, например при запуске функции updateLanguage заново добавляются еще 1 экземпляры других классов.

Возникает вопрос, если я создаю общую переменную с типом данных (до конструктора класса), например
Код AS3:

private var some:ClassA

и потом уже в ходе методов её дается значение
Код AS3:

some = new ClassA("eng")

я всегда думал что если задать этой переменной новое значение
Код AS3:

some = new ClassA("rus")

она проста перезапишется, а слушатели на неё сохраняться. Но выходит как то все по другому, получается мне её надо удалять с displayList, задавать заново значение, и опять добавлять на stage.

В общем, как мне правильно перезаписать имеющуюся переменную?
P.S. и что происходит с переменной если до конструктора я объявляю её как
Код AS3:

privatе var some:ClassA = new ClassA(paramA);

а потом меняю её значение?
Код AS3:

some = new ClassA(paramB);


AlexLucas 22.04.2013 18:52

some - это просто ссылка. Когда вы переопределяете some, вы создаёте новый объект, у которого нет никаких слушателей (видимо вы не вешаете слушатели при инициализации), и вы просто заставляете some указывать на этот новый объект.
На ссылку слушатели не вешаются, они вешаются на объекты.

pomuс 22.04.2013 19:12

ох, у меня голова уже плохо соображает, поэтому еще раз уточню на примере

вот ситуация
Код AS3:

private var _contacts:TextField                = new TextField()// это перед конструктором
 
//Первый запуск приложения
 
case rus_btn:
Settings.lan                = "rus";
break;
 
case eng_btn:
Settings.lan                = "eng";
break;
 
//далее ставлю настройки
                        _contacts.embedFonts                = true;
                        _contacts.mouseEnabled                = false;
                        _contacts.selectable                = false;
                        _contacts.autoSize                        = TextFieldAutoSize.LEFT;
                        _contacts.setTextFormat(TextEditor.contact);
                        _contacts.y                                        = -1;
                        _contacts.x                                        = 10;
 
                        _contact_btn.graphics.beginFill(0xFFFFFF, 0);
                        _contact_btn.graphics.drawRect(0,0, _contacts.width+20, 25);
                        _contact_btn.graphics.endFill();
                        _contact_btn.addChild(_contacts);
                        addChild(_contact_btn);
 
 
// и вот тут отдаю значение текстовому полю
 
        if (Settings.lan == "rus") {
                                _contacts.text                                = "контакты";
                        }
                        else {
                                _contacts.text                                = "contacts";
                        }

непонятно почему текст не заполняется....

Вы сказали что some является ссылкой, но в каком случае? ведь написав var some:ClassA = new ClassA я создаю экземпляр класса, разве не так?

AlexLucas 22.04.2013 19:52

Возможно какая-то настройка (там где вы "ставите настройки" полю _contacts) мешает. Комментируйте и смотрите что мешает.
И я не вижу чтоб вы _contacts где-то переопределили, не вижу связи между кодом и вопросом в первом сообщении.

MoHaX 22.04.2013 20:04

Оператор new создает новый экземпляр класса, тут ничего удивительного.
Если не нужно создавать новый экземпляр, то и обращайся к уже созданному, и обновляй данные через специальный метод.

например:

Код AS3:

 var some : ClassA = new ClassA("eng")
 some.update("rus");


pomuс 22.04.2013 21:47

AlexLucas методом подбора оказалось что надо прописывать формат как setDefaultFormat
А что касаемо связи, мне так думалось что это как то могло влиять с местом обозначения переменной
MoHaX вообще так и планировалось изначально, но есть сложные элементы, например как меню-аккардион, где создание элементов и назначение текстового поля уже происходит в циклах. Получается чтобы сменить текстовое значение надо проходится по всем циклам опять. Вот я и подумал что просто было бы проще перезапустить функцию создания меню, уже с новой языковой переменной.
Код AS3:

var btnArr:Array                                = new Array();
                        var subBtnArr:Array                                = new Array();
 
                        for (var i:int = 0; i < _totalBtn; i++ ) {
                                var btn:MenuItem                        = new MenuItem(catXMLList[i].@[Settings.lan]);
 
                                if (catXMLList[i].children()[0].name() == "position") {                                // Если первый ребенок в XMLList - тег position, то это кнопка без дополнительных элементов. Отсылаем ей её xml
                                        var _xml:XML                        = catXMLList[i].children()[0];
                                        btn.myXML                                = _xml;
                                        btn.addEventListener("OPEN_POSITION", blackAnimation);
                                }
                                btnArr.push(btn);

Сейчас немного отдохнул и увидел что можно просто пройтись по массиву и назначит по ним значения

Так все- таки чтобы разобраться с этим вопросом навсегда, если я создаю
Код AS3:

var some : ClassA = new ClassA(param1)

а потом пишу в методе
Код AS3:

some = new ClassA(param2)

что происходит 1) со слушателями 2) с самими элементами если они были добавлены на сцену 3) с самой some после второго обозначения
Влияет ли это как то на загрязнения памяти?

Wolsh 22.04.2013 22:22

Переменная это ссылка (всегда, кроме простых типов Number и String).
Слово "ссылка" означает указание на область памяти, в которой хранится Объект.
Когда Вы пишете ссылка.method(), Вы вызываете метод Объекта, на который указывает ссылка.
А есть операции с самой ссылкой, например ссылка = ...
Когда Вы пишете ссылка = new Объект(), оператор new создает новый Объект в новой области памяти, а ссылка с этого момента указывает на него. "Старый" объект так и остается в памяти, Вы меняете только значение ссылки (поэтому она называется переменной. Объект же не может быть "переменным")))) Поэтому
1) слушатели, подписанные на события первого объекта, не станут слушателями событий нового объекта.
2) первый объект так и останется на сцене, ведь никто его не удалял из дисплей-листа.
3) будет указывать на второй объект.
4) естественно, если первый объект больше не нужен, его надо уничтожить, то есть сделать доступным для Сборщика Мусора. Для этого нужно удалить все ссылки на этот объект (в том числе удалить его из списка отображения, если он дисплейный, так как любой контейнер имеет ссылки на своих детей, а так же удалить все подписки этого объекта на события других объектов — они тоже хранят на него ссылку). Если на объект (область памяти) не останется ни одной ссылки, им никто никогда не сможет воспользоваться, и Сборщик Мусора со временем очистит эту область памяти.

pomuс 23.04.2013 11:54

Спасибо за подробное разъяснение
Цитата:

Сообщение от Wolsh (Сообщение 1130855)
естественно, если первый объект больше не нужен, его надо уничтожить, то есть сделать доступным для Сборщика Мусора. Для этого нужно удалить все ссылки на этот объект

Но ведь не всегда легко уследить, где же остались зацепки на объект, если это большой проект. В флеше не было расчета на подобное, например как то обнулить объект, и чтобы этот сборщик удалил все хвосты?
(хотя подозреваю что если такое может привести к ошибкам и выбросу из флешки)

Wolsh 23.04.2013 14:16

Я не думаю, что "за этим" уследить сложнее, чем за ситуацией когда кто-то может удалить объект явной директивой (как сделано в некоторых языках), а другие объекты не знают об этом и попытаются к нему обратиться, что, конечно же, вызовет исключение. Да и заботиться постоянно об удалении каждого объекта вручную — то еще развлечение. Есть сторонники как одного, так и другого подхода, но оба они не идеальны и холивар разводить смысла нет. При внимательном соблюдении иерархии и ограничении прав доступа уследить за ссылками совсем не сложно, хотя, конечно, требует понимания некоторых механизмов, подписки на события и списка отображения например.

MoHaX 24.04.2013 00:44

Цитата:

Сообщение от pomuс (Сообщение 1130903)
Но ведь не всегда легко уследить, где же остались зацепки на объект, если это большой проект. В флеше не было расчета на подобное, например как то обнулить объект, и чтобы этот сборщик удалил все хвосты?
(хотя подозреваю что если такое может привести к ошибкам и выбросу из флешки)

Хорошей практикой является создание метода деструктор в котором зануляются все внешние ссылки, и производится отписка от событий.


Часовой пояс GMT +4, время: 15:49.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.