Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Закрытая тема
Старый 24.06.2009, 15:12
giir вне форума Посмотреть профиль Отправить личное сообщение для giir Найти все сообщения от giir
  № 1  
giir

Регистрация: Jun 2009
Сообщений: 13
По умолчанию Удаление объектов в АС3

Насколько я знаю объекты в АС3 удаляются так же как в java, т.е. когда на объект не остается ссылок он автоматом удаляется.
Так вот у меня возникла небольшая проблема. Код, конечно, гораздо сложнее, но отразить самую суть приведу лишь кусок:
Код AS3:
// MovieClip добавляется в stage (General.getStage() - возвращает stage)
// Diver - наследуется от мувиклипа
General.getStage().addChild(new Diver());
 
// Hero  - наследуется от мувиклипа
General.getStage().addChild(new Hero());
...
// В классе Diver при опр. условиях устанавливаем статическую переменную Hero.enemy
Hero.enemy=this;
 
// В классе Hero при опр. условиях удаляем из детей у stage объект типа Diver и зануляем ссылку Hero.enemy
if(Hero.enemy!=null){
  if (Hero.enemy.parent != null) {
    Hero.enemy.parent.removeChild(Hero.enemy);
    Hero.enemy = null;
  }
}
Казалось бы - объект Diver должен удалится если и не совсем,то уж по крайтей мере из детей stage точно!
Ан нет... срабатывает Diver.onEnterFrame()...

Коллеги, подскажите, пожалуйста что я делаю не так... ну или если мой код совсем не поймете, то хотябы просто объясните как удалить объект совсем, чтобы не срабатывало у instance не срабатывало событие Event.ENTER_FRAME.

Заранее спасибо!!!

Старый 24.06.2009, 15:21
Gal4enochek вне форума Посмотреть профиль Отправить личное сообщение для Gal4enochek Найти все сообщения от Gal4enochek
  № 2  
Gal4enochek

Регистрация: May 2008
Адрес: Днепропетровск
Сообщений: 151
Отправить сообщение для Gal4enochek с помощью ICQ
Даже если вы удалили объект, листнер на Event.ENTER_FRAME, который вы к нему прикрепили, все равно останется. Во такая вот фича.
Так что для объектов, которым вы цепляли листнеры нужно определять деструктор, который их потом буду удалять.
Например
Код AS3:
public class Hero extends MovieClip{
   //...
   // код вашего класса
   // ....
   public function destroy():void{
        if (this.willTriger(Event.ENTER_FRAME))
             this.removeEventListener(Event.ENTER_FRAME, ваш_обработчик);
   }  
}
И тогда перед удаление вызывать деструктор.

Старый 24.06.2009, 16:15
2morrowMan вне форума Посмотреть профиль Отправить личное сообщение для 2morrowMan Найти все сообщения от 2morrowMan
  № 3  
2morrowMan
 
Аватар для 2morrowMan

Регистрация: Aug 2007
Сообщений: 467
Цитата:
Сообщение от giir Посмотреть сообщение
т.е. когда на объект не остается ссылок он автоматом удаляется.
Это не так. Он удаляется не автоматом, не пулеметом. Удаляет объект Garbage Collector и не обязательно сразу же, после того как на объект не остается ссылок.
__________________
Лучше быть умным и иногда делать глупости, чем глупым и постоянно умничать!

Старый 24.06.2009, 16:33
dimarik вне форума Посмотреть профиль Отправить личное сообщение для dimarik Найти все сообщения от dimarik
  № 4  
dimarik
.
 
Аватар для dimarik

модератор форума
Регистрация: Sep 2003
Адрес: Москва
Сообщений: 4,630
Записей в блоге: 20
Цитата:
Сообщение от Gal4enochek Посмотреть сообщение
Код AS3:
if (this.willTriger(Event.ENTER_FRAME)) {
    this.removeEventListener(Event.ENTER_FRAME, ваш_обработчик);
}
Gal4enochek, я хотел уточнить, с чем связана проверка this.willTriger(Event.ENTER_FRAME, ваш_обработчик) на наличие слушателя заданного события в цепочке родителей этого this в иерархии display list'а? Если this не слушает такое событие, а, предположим, его parent это делает, то проверка вернет true. Теперь Вы удаляете [this.ваш_обработчик] как несуществующий слушатель. Хорошо, что эксепшн не генерируется для removeEventListener.
__________________
Воспитан в TimeZero. Работаю в Mail.ru.

Старый 24.06.2009, 17:01
Gal4enochek вне форума Посмотреть профиль Отправить личное сообщение для Gal4enochek Найти все сообщения от Gal4enochek
  № 5  
Gal4enochek

Регистрация: May 2008
Адрес: Днепропетровск
Сообщений: 151
Отправить сообщение для Gal4enochek с помощью ICQ
dimarik, наверное я действительно ошиблась. В таких случаях нужно использовать hasEventListener()? Или вообще без проверок можно обойтись?

Старый 24.06.2009, 17:06
giir вне форума Посмотреть профиль Отправить личное сообщение для giir Найти все сообщения от giir
  № 6  
giir

Регистрация: Jun 2009
Сообщений: 13
Вообще непонятное творится.. в ролике fla объявлен класс General как Document Class.
Из его конструктора последовательно вызываются др. конструкторы, которые добавляются на stage после создания.. т.е.
Код AS3:
stage.addChild(new BaseEnemy())
в конструкторе для BaseEnemy вываливаю логи. Запускаю ролик и судя по логам к своему великому удивлению замечаю, что конструктор BaseEnemy() запускается периодично все время.
Может кто знает :
1) Означает ли это что создается новый инстанс типа BaseEnemy или просто вызывается сам метод.
2) Как от этого избавится, очень надо, чтобы new BaseEnemy вызвалось 1 раз.

PS: спасибо за removeEventListener хотя пока и не помогло, но кое-что прояснилось - 100% в будущем бы на это напоролся...

Старый 24.06.2009, 17:11
dimarik вне форума Посмотреть профиль Отправить личное сообщение для dimarik Найти все сообщения от dimarik
  № 7  
dimarik
.
 
Аватар для dimarik

модератор форума
Регистрация: Sep 2003
Адрес: Москва
Сообщений: 4,630
Записей в блоге: 20
Цитата:
Сообщение от Gal4enochek Посмотреть сообщение
dimarik, наверное я действительно ошиблась. В таких случаях нужно использовать hasEventListener()? Или вообще без проверок можно обойтись?
Можно и hasEventListener, и без проверок. Эксепшн-то не генерится.
И да, если Вы обращаетесь к методам родительских классов, то лучше употреблять словечко super. Сразу все понятно, что метод где-то выше в цепочке наследования.

Код AS3:
if ( super.hasEventListener(Event.ENTER_FRAME) ) {
    super.removeEventListener(Event.ENTER_FRAME, this.handler_eneterFrame);
}
__________________
Воспитан в TimeZero. Работаю в Mail.ru.

Старый 24.06.2009, 18:45
silin вне форума Посмотреть профиль Посетить домашнюю страницу silin Найти все сообщения от silin
  № 8  
silin
 
Аватар для silin

блогер
Регистрация: Mar 2003
Адрес: Моск. обл.
Сообщений: 5,269
Записей в блоге: 6
почти официальный запуск GC, правда только для 10-ки
Код AS3:
package  silin.utils
{
	import flash.display.Loader;
	import flash.events.Event;
	import flash.utils.ByteArray;
 
	/**
	 * утитилита для принудительного вызова GC за счет 10-чного unloadAndStop<br>
	 *: грузим-выгружаем, походу запускается GC
	 * @author silin
	 */
	public class GCForcer 
	{
		private static const LOADER:Loader = new Loader();
		private static const GIF:Array = [
			71, 73, 70, 56, 57, 97, 1, 0, 1, 0, -128, 0, 0, -1, -1, -1, 0, 0, 0, 33, -7,
			4, 0, 7, 0, -1, 0, 44, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, 68, 1, 0, 59
		];
 
		public function GCForcer() 
		{
			trace ("GCForcer is a static class and should not be instantiated.");
		}
 
		public static function force():void
		{
 
			LOADER.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplteteHandler);
 
			var ba:ByteArray = new ByteArray();
			for (var i:int = 0; i < GIF.length; i++) 
			{
				ba.writeByte(GIF[i]);
			}
 
			LOADER.loadBytes(ba);
		}
 
		static private function loaderComplteteHandler(evnt:Event):void 
		{
			LOADER.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaderComplteteHandler);
			try 
			{
				LOADER.unloadAndStop();
			}catch (err:Error) { };
 
		}
 
	}
}
тест:
Код AS3:
package 
{
	import flash.display.Sprite;
	import flash.events.*;
	import silin.utils.GCForcer;
 
 
	public class Main extends Sprite 
	{
 
		private var _test:Sprite = new Sprite();
		private var _counter:int = 0;
 
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
 
		}
 
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			_test.addEventListener(Event.ENTER_FRAME, testEnterFrameHandler);
			//смотрим по клику
			stage.addEventListener(MouseEvent.CLICK, stageClickHandler);
 
		}
 
		private function testEnterFrameHandler(evnt:Event):void 
		{
			_counter++;
			trace( "_counter : " + _counter );
		}
 
		private function stageClickHandler(evnt:MouseEvent):void 
		{
 
			_test = null;
			//без вызова GCForcer.force трейс в testEnterFrameHandler продолжит работать неопределенно долго
			GCForcer.force();//вызов unloadAndStop 
		}
 
	}
 
}

Старый 24.06.2009, 21:03
2morrowMan вне форума Посмотреть профиль Отправить личное сообщение для 2morrowMan Найти все сообщения от 2morrowMan
  № 9  
2morrowMan
 
Аватар для 2morrowMan

Регистрация: Aug 2007
Сообщений: 467
Цитата:
Сообщение от dimarik Посмотреть сообщение
И да, если Вы обращаетесь к методам родительских классов, то лучше употреблять словечко super. Сразу все понятно, что метод где-то выше в цепочке наследования.
Все и так понятно. Это ненужный выпендреж и/или попытка писать по "умному". Употребляя super там где не надо можно только усложнить себе разработку. Только не спрашивайте почему.

Добавлено через 1 минуту
silin, циферки в константе GIF что-то значат ?
__________________
Лучше быть умным и иногда делать глупости, чем глупым и постоянно умничать!

Старый 24.06.2009, 21:11
Felicast вне форума Посмотреть профиль Отправить личное сообщение для Felicast Найти все сообщения от Felicast
  № 10  
Felicast
 
Аватар для Felicast

Регистрация: Feb 2008
Адрес: Череповец
Сообщений: 623
Отправить сообщение для Felicast с помощью ICQ
Цитата:
Сообщение от 2morrowMan Посмотреть сообщение
silin, циферки в константе GIF что-то значат ?
судя по всему - это что-то вроде empty.gif
чтобы не загружать с сервера находится прямо во флэшке. прикольное решение
__________________
я могу стать всем, если только захочу

Создать новую тему Закрытая тема Часовой пояс GMT +4, время: 12:23.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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