Форум программистов, компьютерный форум, киберфорум
Наши страницы
ActionScript
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
Wells77
20 / 20 / 3
Регистрация: 16.10.2013
Сообщений: 295
1

Удаление экземпляра класса

17.06.2014, 11:24. Просмотров 848. Ответов 8
Метки нет (Все метки)

Хочу уточнить у вас, если я удаляю экземпляр класса через ремувчайлд, то все дети его с их слушателями событий также удаляются, или остаются в памяти, и нада еще кучу кода писать при удалении, чтоб в ручную сначала поремувать все слушатели дочерних мувиков?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.06.2014, 11:24
Ответы с готовыми решениями:

Удаление экземпляра подкласса
Здравствуйте :) прошу помощи в освоении данного материала. По рекомендации, с недавних пор начал...

Название экземпляра класса
Есть припустим мувик класса k1 и мувик класса k2. Кидаю оба экземпляра на сцену. Теперь как мне...

Помещение экземпляра класса на сцену
Хотел сделать так что бы на сцене появлялся квадрат. Да, банально, но... После того как я создал...

Программное создание экземпляра класса
Вобщем разрабатываю инвентарь для игры и хочу реализовать следующий механизм. -Есть класс...

Создание экземпляра класса игрового времени
Есть основной файл программы и есть класс. В классе описано создание виртуального "времени"....

8
Theoryofgames
253 / 237 / 50
Регистрация: 20.12.2011
Сообщений: 707
17.06.2014, 11:32 2
Слушатели событий остаются и их нужно удалять руками, кроме тех, которые были объявлены со слабой связанностью, в таком случае они удаляются если не остается ни одной ссылки на объект в котором они объявлены (я стараюсь их не использовать, потому что они бывает создают массу проблем).
0
Wells77
20 / 20 / 3
Регистрация: 16.10.2013
Сообщений: 295
17.06.2014, 11:40  [ТС] 3
Вобщем, если правильно понял, если в коде есть addEventListener, то и обязательно должен быть removeEventListener та него? Неужели разрабы не предусмотрели нормальную чистку всех детей? Ведь если я удаляю парента, то логично что мне уже ненужны дети с их слушателями.
0
Theoryofgames
253 / 237 / 50
Регистрация: 20.12.2011
Сообщений: 707
17.06.2014, 11:43 4
Цитата Сообщение от Wells77 Посмотреть сообщение
Ведь если я удаляю парента, то логично что мне уже ненужны дети с их слушателями.
Нелогично, может быть Вы не удаляете его полностью, а временно убираете со сцены, чтобы затем вновь вернуть.
Цитата Сообщение от Wells77 Посмотреть сообщение
Вобщем, если правильно понял, если в коде есть addEventListener, то и обязательно должен быть removeEventListener та него?
Если Вы постоянно пересоздаете объекты, то да, если объект используется повторно, то я обычно добавляют слушатели addedToStage и removedFromStage. RemovedFromStage удаляет все слушатели и добавляет слушатель на addedToStage. AddedToStage удалет слушаетль на removedFromStage и добавляет все слушатели, которые используются в объекте.
1
17.06.2014, 11:43
Wells77
20 / 20 / 3
Регистрация: 16.10.2013
Сообщений: 295
17.06.2014, 11:49  [ТС] 5
Цитата Сообщение от Theoryofgames Посмотреть сообщение
Если Вы постоянно пересоздаете объекты, то да, если объект используется повторно, то я обычно добавляют слушатели addedToStage и removedFromStage. RemovedFromStage удаляет все слушатели и добавляет слушатель на addedToStage. AddedToStage удалет слушаетль на removedFromStage и добавляет все слушатели, которые используются в объекте
А можна поподробнее, желательно с элементарным примером для понимания? Никогда таким не пользовался методом.
0
Theoryofgames
253 / 237 / 50
Регистрация: 20.12.2011
Сообщений: 707
17.06.2014, 11:57 6
Обычно весь этот функционал вытаскивается в базовый класс и методы addListeners и removeListeners наследуются. Если объект планируется удалить можно вызвать деструктор destoy() который уничтожит все слушатели

ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package tnf.ui.dialogs
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    
    public class Test extends Sprite
    {
        /***************static***************/
        
        /***************variables***************/
        
        /***************constructor***************/
        
        public function Test()
        {
            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        }
        
        private function onAddedToStage(event:Event) : void
        {
            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
            addListeners();
        }
        
        private function onRemovedFromStage(event:Event) : void
        {
            removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            removeListeners();
        }
        
        protected function addListeners() : void
        {
            addEventListener(MouseEvent.CLICK,          onMouseClick);
            addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            addEventListener(MouseEvent.MOUSE_UP,       onMouseUp);
        }
        
        protected function removeListeners() : void
        {
            removeEventListener(MouseEvent.CLICK,               onMouseClick);
            removeEventListener(MouseEvent.MOUSE_DOWN,  onMouseDown);
            removeEventListener(MouseEvent.MOUSE_UP,        onMouseUp);
        }
        
        private function onMouseClick(event:MouseEvent) : void  { trace("click"); }
        private function onMouseDown(event:MouseEvent) : void       { trace("down"); }
        private function onMouseUp(event:MouseEvent) : void         { trace("up"); }
        
        /***************interface***************/
        
        public function destroy() : void
        {
            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
            removeListeners();
        }
    }
}
0
Wells77
20 / 20 / 3
Регистрация: 16.10.2013
Сообщений: 295
17.06.2014, 12:32  [ТС] 7
Не совсем понял целесообразность в примере функции destroy(). Если я в мейне где-то делаю
ActionScript 3
1
2
var t:Test=new(Test);
                       addChild(t);
на сцену добавляется экземпляр Тест с 4 слушателями:
ActionScript 3
1
2
3
4
addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
                      addEventListener(MouseEvent.CLICK,          onMouseClick);
            addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            addEventListener(MouseEvent.MOUSE_UP,       onMouseUp);
Потом если делаю в мейне removeChild(t): 4 слушетеля удаляются с памяти, но добавляется слушатель addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);(???).


Вот тут мне обьясните что висит в памяти? раз при удалении добавили слушатель, то переменная t остается висеть и кушать память с 1 слушетелем, хоть и не добавлена на сцену? И я в любой момент могу ее снова добавить на сцену addChild(t), и соответственно добавится 3 слушателя к ней.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
В чем разница, если я мог по onRemovedFromStage(event:Event) не добавлять слушатель addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); И тогда ЕСЛИ Я ПРАВИЛЬНО ПОНИМАЮ ЛОГИКУ, t удалиться с памяти со всема слушателями. И при необходимости я просто заново обьявлю эту переменную
ActionScript 3
1
2
t=new(Test);
                       addChild(t);
Как по мне, пока мне не нужна t с ее функционалом, зачем ее держать в памяти и занимать место ее слушетелем добавления на сцену?
0
Theoryofgames
253 / 237 / 50
Регистрация: 20.12.2011
Сообщений: 707
17.06.2014, 13:00 8
Лучший ответ Сообщение было отмечено Wells77 как решение

Решение

Цитата Сообщение от Wells77 Посмотреть сообщение
Вот тут мне обьясните что висит в памяти? раз при удалении добавили слушатель, то переменная t остается висеть и кушать память с 1 слушетелем, хоть и не добавлена на сцену? И я в любой момент могу ее снова добавить на сцену addChild(t), и соответственно добавится 3 слушателя к ней.
Да, Вы все правильно поняли.
Цитата Сообщение от Wells77 Посмотреть сообщение
В чем разница, если я мог по onRemovedFromStage(event:Event) не добавлять слушатель addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); И тогда ЕСЛИ Я ПРАВИЛЬНО ПОНИМАЮ ЛОГИКУ, t удалиться с памяти со всема слушателями. И при необходимости я просто заново обьявлю эту переменную
Разница заключается в том, что вместо того, чтобы удалять объект полностью, мы как бы усыпляем его, заставляя потреблять меньше ресурсов, чем в обычном режиме (1 слушатель против 4). Затем в любой момент мы его можем разбудить и нам не нужно будет создавать новый экземпляр.
Цитата Сообщение от Wells77 Посмотреть сообщение
Как по мне, пока мне не нужна t с ее функционалом, зачем ее держать в памяти и занимать место ее слушетелем добавления на сцену?
Нужно это затем, что на создание нового экземпляра тратится гораздо больше ресурсов, чем на оживление спящего и поэтому, вместо создания нового экзепляра лучше создать пул из неиспользуемых объектов и помере необходимости вытаскивать из него спящие экземпляры и оживлять их.
1
Wells77
20 / 20 / 3
Регистрация: 16.10.2013
Сообщений: 295
17.06.2014, 16:00  [ТС] 9
Цитата Сообщение от Theoryofgames Посмотреть сообщение
Нужно это затем, что на создание нового экземпляра тратится гораздо больше ресурсов, чем на оживление спящего и поэтому, вместо создания нового экзепляра лучше создать пул из неиспользуемых объектов и помере необходимости вытаскивать из него спящие экземпляры и оживлять их.
Если это так, что на оживление используется меньше ресурсов чем на создание нового экземпляра, то скорее это рационально использовать, если класс имеет сложную графику, тогда наверное проще усыпить чем заново создавать и выводить на сцену. В этом то и хочу разобраться, у меня например классы уровней в игре (понятное дело много графики и слушателей), так вот если таких уровней 10 например, то их лучше усыплять все, удаляя только со сцены и пробуждая в нужный момент (когда например по ходу игры сам выбираеш один из пройденых уровней) или же создавать новый.

Добавлено через 1 минуту
Хотя уже отклонились от темы Ответ основной по теме я услышал. Еще раз спасибо.

Добавлено через 28 минут
И для полноты информации по теме кому тоже интересно, отписал один флешер:
Теоретический аспект:
1) removeChild не удаляет экземпляры объектов. Объект будет удален сборщиком мусора через некоторое непредсказуемое время после того момента, когда на него не останется ссылок от "живых" объектов и со стека.
2) Если ты создал объект А, у него есть дети C1, C2, C3, и каждый из них подписан на событие on click, и объект А становится доступен для сборщика мусора, то наличие событий на C1, C2, C3 не помешает сборщику мусора выполнить свою работу. Эти объекты будут успешно убраны из памяти. Поэтому ты НЕ ОБЯЗАН их вручную убирать.
3) Однако, все это время события будут активны. Для события on click это не важно, а, как абсолютно верно заметил TheRabbit, on enter frame будут вызываться до некоторого случайного момента, пока не будет собран.
4) Наличие слушателя обычно образует кольцевую ссылку C1 --> listener, listener --> C1. Скорее всего ты подписываешь метод объекта, за кадром в АС3 этот создает "замыкание" (указатель на метод объект + указатель на экземпляр).
5) Как мы выяснили в большом_теоретико_практическом_сраче_про_СМ, флэш имеет особый оптимальный алгоритм для сбора объектов, на которых вообще нет ссылок (например, нет кольцевых ссылок).

Практические следствия:
1) Если точно знаешь, что делаешь, не удаляй обработчики событий (например, ты грохаешь главное меню в десктопной флешке, и там только события мыши). Только внимательно убедись, что понимаешь последствия (например, enter frame не оставил случайно).
2) Ручное убирание слушателей упростит работу GC. Скорее всего, как часто напоминает нам TheRabbit, это крайне желательно делать в мобильных приложениях.
3) Отсутствие ручного убирания слушателей может породить крайне неожиданные эффекты. Например, класс Game подписан на событие в своем ребенке Avatar. А Avatar еще где-то в пылу битвы был помещен в синглетон (ну мало ли). Вся эта конструкция не сможет быть убрана из памяти.

Замечание: да отсутствие removeAllEvents - недостаток API Flash.
0
17.06.2014, 16:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.06.2014, 16:00

Удаление экземпляра класса в функции самого класса (Ошибка при отладке)
Допустим, у нас есть класс Buffer, который хранит в себе указатель на класс некоторой матрицы и...

Удаление экземпляра класса
Здравствуйте. Пытаюсь написать игру. В игре по заданным координатам создаётся экземпляр класса....

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru