Форум 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=122388)

2K WebStudio 10.03.2009 15:23

Цитата:

Сообщение от __etc (Сообщение 804343)
В правильно начатом проекте проблемы отписывания от событий в принципе не возникнет.

согласен. проблемы нет.
я просто хотел понять, есть ли необходимость удалять всех детей и слушателей, если я хочу удалить родителя.

etc 10.03.2009 15:25

Удаление детей должен произвести сам удаляемый объект.

2K WebStudio 10.03.2009 15:27

Цитата:

Сообщение от __etc (Сообщение 804346)
Удаление детей должен произвести сам удаляемый объект.

как и удаление их слушателей.

iflamberg 10.03.2009 15:38

в общем случае, я делаю метод destroy, который запускает destroy у всех детей, а потом зануляет свои ссылки и убивает слушателей. Уж свои-то листенеры объект должен знать.

2K WebStudio 10.03.2009 15:46

Цитата:

Сообщение от iflamberg (Сообщение 804350)
в общем случае, я делаю метод destroy, который запускает destroy у всех детей, а потом зануляет свои ссылки и убивает слушателей. Уж свои-то листенеры объект должен знать.

зануляет ссылки на себя? как он узнает о них?

iflamberg 10.03.2009 16:17

зануляет ссылки внутри себя. Убить ссылку на него - задача уже его родителя.
Непонимаю в чем проблемы, любой программист, который учился программированию на cpp или даже pascal имеет понимание о том, как освободить память.

etc 10.03.2009 16:26

Цитата:

Сообщение от 2K WebStudio (Сообщение 804348)
как и удаление их слушателей.

Если родитель слушает события детей, то он должен от детей отписаться.

2K WebStudio 10.03.2009 16:57

Цитата:

Сообщение от iflamberg (Сообщение 804361)
зануляет ссылки внутри себя. Убить ссылку на него - задача уже его родителя.
Непонимаю в чем проблемы, любой программист, который учился программированию на cpp или даже pascal имеет понимание о том, как освободить память.

изучаю специфику флеша. мало ли что.
меня просто удивила формулировка вашего ответа - потому и уточнил.

Цитата:

Сообщение от __etc (Сообщение 804364)
Если родитель слушает события детей, то он должен от детей отписаться.

естественно.

Румеев 11.03.2009 23:15

Присоединяюсь к __etc.
Но сделаю замечание: занулять все ссылки, удалять всех детей и делать кучу других лишних действий (в общем случае) - это гемор чистой воды.
Нужно занулять (и снимать слушатели) только то, что действительно необходимо ;)
Деструкторы в классах тогда будут занимать больше чем сами классы ))
Зануления и удаления могут немного ускорить процесс "mark" у GC (garbage collector), не более.
Важно четко и правильно понимать как флэш работает с памятью. Тогда проблем с "нужно/не нужно" не будет.

P.S. Какие бы профи не были в команде разрабов, без Flex Profiler порой не обойтись ;)
P.P.P.P.P.S. ну и те кто пишут свои проги в Flash IDE, не прогеры... )))) гы

s8000_1 12.03.2009 02:51

Цитата:

Сообщение от iflamberg
флеш не настолько умный. Все ссылки лучше занулять(включая удаляемых детей).

Неверно. Флэш умный.

Цитата:

Сообщение от 2K WebStudio
есть ли необходимость удалять всех детей

Нет такой необходимости.

Цитата:

Сообщение от __etc
Удаление детей должен произвести сам удаляемый объект.

Разве? Я ни в одном примере не видел, чтобы в каждом классе писались деструкторы, удаляющие всех детей объекта, на который нигде не осталось ссылок. Если у объекта там что-то внутри друг на друга ссылается, оно все будет удалено пачкой.

Цитата:

Сообщение от iflamberg
в общем случае, я делаю метод destroy, который запускает destroy у всех детей, а потом зануляет свои ссылки

Смысл? Эта работа бесполезна :) Как уже сказали выше, такой подход может ускорить GC, и все.

Цитата:

Сообщение от iflamberg
Непонимаю в чем проблемы, любой программист, который учился программированию на cpp или даже pascal имеет понимание о том, как освободить память.

Так AS3 не паскаль или cpp. В AS3 есть сборщик мусора как бы.


В общем-то проверьте профайлером:

Код AS3:

package{
        import flash.display.*;
        import flash.events.*;
        public class Test extends Sprite{
                var mcs:Array;
                function Test(){
                        graphics.beginFill(0xFF00FF);
                        graphics.drawRect(0,0,50, 50);
                        mcs = new Array();
                        var mc:Sprite;
                        for (var i:uint = 0; i< 100; i++){
                                mc = new Sprite();
                                mc.addEventListener(MouseEvent.CLICK, onChildClick);
                                mcs.push(mc);
                        }
                }
                private function onChildClick(e:Event):void{
                        trace (e.currentTarget);
                }
        }
}

Код AS3:

package {
        import flash.display.*;
        import flash.events.*;
        public class MemoryTest extends Sprite {
                var bt:Sprite;
                var bt1:Sprite;
                var mc:Sprite;
                function MemoryTest() {
 
                        bt = new Sprite();
                        bt.graphics.beginFill(0);
                        bt.graphics.drawRect(0,0,100,100);
                        stage.addChild(bt);
 
                        bt1 = new Sprite();
                        bt1.graphics.beginFill(0xFF0000);
                        bt1.graphics.drawRect(0,0, 100,100);
                        bt1.x = 100;
                        stage.addChild(bt1);
 
                        bt.addEventListener(MouseEvent.CLICK, createObjects);
                        bt1.addEventListener(MouseEvent.CLICK, removeObjects);
 
                }
                function createObjects(e:Event):void {
                        if (mc) {
                                return;
                        }
                        mc = new Test();
                        mc.addEventListener(MouseEvent.CLICK, clickListener);
                        mc.y = 100;
                        stage.addChild(mc);
                }
                function removeObjects(e:Event):void {
                        if (!mc) {
                                return;
                        }
                        stage.removeChild(mc);
                        mc = null;
                }
                function clickListener(e:Event):void{
                }
        }
}

Все прекрасно удаляется из памяти и без ручного обнуления всего и вся. Утечек памяти нет. Версия плеера 10.12.36.

Насчет удаления слушателей надо понимать лишь, что такое слушатель, и как оно работает. А работает оно как-то так:
http://www.javaworld.com/javaworld/j...04-events.html
child.addEventListener(event, parentFunc) в массив _listeners ребенка кладет ссылку на parentFunc. А т. к. это дело изолировано в ребенке, то ничего казалось бы не помешает флэшу удалить спокойно child из памяти, если на него не осталось ссылок. Но из-за особенности флэшовских событий (bubbling) в родителе тоже возможно сохраняются ссылки на ребенка - мое предположение. Поэтому:
Цитата:

Сообщение от __etc
Если родитель слушает события детей, то он должен от детей отписаться.

Хотя ИМХО это банально перестраховка (см. пример для профайлера выше), ибо по-хорошему методы addChild и removeChild класса DisplayObject должны быть умными и удалять всех лишних слушателей из Event Flow автоматически. Может быть в прошлых версиях плеера был какой-то баг, связанный с удалением объектов? __etc, почему именно-то Вы везде рекомендуете удалять слушателей?

Кстати, может кто знает, нет ли где-нибудь статьи, в которой описана модель событий флэша на очень детальном уровне? Т. е. фактически как написать класс EventDispatcher идентичный флэшовому.


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

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