Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Создание объекта без ключевого слова var (http://www.flasher.ru/forum/showthread.php?t=158406)

Zolza 19.06.2011 15:31

Создание объекта без ключевого слова var
 
Увидел такой код в статье про MVC:
Код AS3:

new BaseController(this);

Затем, где-то рядом было так:
Код AS3:

var controller:BaseController = new BaseController(this);

Вопрос не про MVC, нет.

Получается, можно создавать экземпляры объектов напрямую через new без ключевого слова var ? Какие подводные камни при этом существуют, и каким из двух способов и когда стоит пользоваться?

alatar 19.06.2011 16:23

В первом случае у вас не будет ссылки на объект. Соответственно вы ничего не сможете с ним сделать (если он сам себя не добавить куда-нибудь), и при первой возможности GC его удалит.

S-ed 19.06.2011 16:26

Но хуже то, что первый будет доступен для сборщика с момента создания.

Crazy 19.06.2011 16:29

Про GC: очень типичная ошибка.

Hint: что будет, если объект в конструкторе подпишется на события? Или просто использует переданный ему в конструкторе параметр и заассайнит этому объекту ссылку на себя?

alatar 19.06.2011 16:31

Будет то, что написано в скобках. Появится ссылка на объект, со всеми вытекающими.

КорДум 19.06.2011 16:31

Не забывайте про
Код AS3:

addChild(new MyMovieClip());

Вот так GC ничего не заберет, но ссылку на экземпляр класса MyMovieClip можно получить только через перебор в дисплей листе по индексам.
Конструктор - это, если грубо говоря, функция, которая возвращает экземпляр класса. Хотя конструктор - это не функция и не метод, это конструктор, если занудничать.

Crazy 19.06.2011 16:32

Цитата:

Сообщение от Zolza (Сообщение 1004776)
Получается, можно создавать экземпляры объектов напрямую через new без ключевого слова var ? Какие подводные камни при этом существуют, и каким из двух способов и когда стоит пользоваться?

Ключевое слово "var" вообще не имеет никакого отношения к созданию объектов.

Когда стоит пользоваться? Когда результат new передается параметром в другой метод.

Код AS3:

foo.setBar(new Bar());

Делать как в приведенном Вами примере -- не стоит.

Zolza 19.06.2011 16:47

Всем спасибо

S-ed 19.06.2011 17:15

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

etc 19.06.2011 18:16

Цитата:

Сообщение от S-ed (Сообщение 1004813)
Crazy
Наличие подписки на событие не является критерием для исключения из списка сборщика

Является, если на источник события есть внешние ссылки.

S-ed 19.06.2011 18:32

etc
Под подпиской, я подразумевал наличие приемника. Простите.

Crazy 19.06.2011 20:16

Цитата:

Сообщение от S-ed (Сообщение 1004813)
Crazy
Наличие подписки на событие не является критерием для исключения из списка сборщика (для этого пишут деструкторы, хотя в AS3 их нет в явном виде). Я думаю, что это также распространенная ошибка, не отписывать удаляемый объект и забывать отключать в нем таймеры и останавливать каретку (и тоже для детей).
(тоесть, даже после присвоения null все процессы в экземпляре буду протекать как и раньше)

Коллега, Вы противоречите сами себе. Почему "не отписывать удаляемый объект" есть ошибка, если "наличие подписки на событие не является критерием для исключения из списка сборщика"? Вы уж определитесь -- а потом, быть может, и подискутируем. А пока Ваша точка зрения категорически загадочна.

S-ed 19.06.2011 21:32

Crazy
В чем противоречие?

Объект создан и ссылка на объект присвоена некой переменной.
Подписан как приемник.
Ссылка на объект обнулена. //с этого момента объект доступен для сборки
Объект продолжает принимать сообщения.//в этом и есть ошибка, надо было отписать его до удаления ссылки
Объект удален сборщиком.

Gaen 19.06.2011 21:52

Объект подписан как приемник = у источника в массиве listeners есть на него ссылка.

i.o. 19.06.2011 22:10

Цитата:

Сообщение от Gaen (Сообщение 1004870)
Объект подписан как приемник = у источника в массиве listeners есть на него ссылка.

может про подпись на событие с weakRef=true шла речь...

etc 19.06.2011 23:15

Цитата:

Сообщение от S-ed (Сообщение 1004862)
Crazy//с этого момента объект доступен для сборки

Ещё нет, если не подписан с weakReference.

S-ed 19.06.2011 23:15

i.o.
Точно. Все никак не мог вспомнить. Знал что есть ссылки в таблице слушателей, и знал что несмотря на это слушатель может быть удален, но почему - забыл. useWeakReference

Вот код что ввел меня в заблуждение:
Код AS3:

var s1:Sprite = new Sprite();
var s2:Sprite = new Sprite();
s1.addEventListener(Event.ENTER_FRAME, enterFrameListener);
s2.addEventListener(Event.ENTER_FRAME, enterFrameListener);
s1.name = 'Sprite 1';
s2.name = 'Sprite 2';
 
var timer:Timer = new Timer(1,0);
timer.addEventListener(TimerEvent.TIMER, timerListener);
timer.start();
 
s2 = null; /*обнуляется в самом начале, однако, программа продолжает валить в консоль
сообщения еще несколько секунд*/

 
function timerListener (e:TimerEvent):void
{
        new TextField();
}
 
function enterFrameListener( e:Event ):void
{
        trace(e.target.name, timer.currentCount, System.totalMemory);
}

Взят из Мука и немного изменен.
Код:

Sprite 1 742 32137216
Sprite 2 742 32137216
Sprite 1 745 32141312
Sprite 2 745 32141312 - тут коллектор забрал s2
Sprite 1 747 30515200
Sprite 1 750 30515200
Sprite 1 753 30515200
Sprite 1 756 30519296
Sprite 1 759 30523392


etc 20.06.2011 13:50

Цитата:

Сообщение от S-ed (Сообщение 1004887)
i.o.
Точно. Все никак не мог вспомнить. Знал что есть ссылки в таблице слушателей, и знал что несмотря на это слушатель может быть удален, но почему - забыл. useWeakReference

Взят из Мука и немного изменен.
Код:

Sprite 1 742 32137216
Sprite 2 742 32137216
Sprite 1 745 32141312
Sprite 2 745 32141312 - тут коллектор забрал s2
Sprite 1 747 30515200
Sprite 1 750 30515200
Sprite 1 753 30515200
Sprite 1 756 30519296
Sprite 1 759 30523392


Здесь нет weakReference, поэтому работать не будет.

S-ed 20.06.2011 13:54

etc
Ммм...не совсем понял. Что не будет работать?
Этот трейс я не руками писал, это то что выводится в консоль...(ну, за исключением "забрал" =))

etc 20.06.2011 13:59

Цитата:

Сообщение от S-ed (Сообщение 1005023)
etc
Ммм...не совсем понял. Что не будет работать?
Этот трейс я не руками писал, это то что выводится в консоль...(ну, за исключением "забрал" =))

Там нет weakReference, мы будем получать Sprite 1 и Sprite 2 бесконечно.

S-ed 20.06.2011 14:46

Ну. Проверьте код.
У меня работает. На CS4 и CS5.

etc 20.06.2011 14:46

Цитата:

Сообщение от S-ed (Сообщение 1005050)
Ну. Проверьте код.
У меня работает. На CS4 и CS5.

Он работает, только демонстрации работы GC — нет.

S-ed 20.06.2011 16:12

Цитата:

мы будем получать Sprite 1 и Sprite 2 бесконечно
Цитата:

Он работает, только демонстрации работы GC — нет.
У меня Sprite 1 генерится бесконечно (ждал пару минут), а вот Sprite 2 пропадает через секунду-две (иногда висит 10, но это когда никаких программ не запущено). Или Вы хотите чтоб GC в консоль писал когда собирает?

Этот код удаляет ссылку через 5 секунд:
Код AS3:

var s1:Sprite = new Sprite();
var s2:Sprite = new Sprite();
s1.addEventListener(Event.ENTER_FRAME, enterFrameListener);
s2.addEventListener(Event.ENTER_FRAME, enterFrameListener);
s1.name = 'Sprite 1';
s2.name = 'Sprite 2';
 
var timer:Timer = new Timer(1,0);
timer.addEventListener(TimerEvent.TIMER, timerListener);
timer.start();
 
var timer2:Timer = new Timer(5000,1);
timer2.addEventListener(TimerEvent.TIMER, timerSwitch);
timer2.start();
 
function timerListener (e:TimerEvent):void
{
        new TextField();
}
 
function enterFrameListener( e:Event ):void
{
        trace(e.target.name, timer.currentCount, System.totalMemory);
}
 
function timerSwitch (e:TimerEvent):void
{
        s2 = null;
        trace('Removing Sprite 2, s2 =', s2);
}

Трейс:
Код:

Sprite 1 1166 27508736
Sprite 2 1166 27508736
Sprite 1 1176 27516928
Sprite 2 1176 27516928
Sprite 1 1184 27529216
Sprite 2 1184 27529216
Sprite 1 1194 27549696
Sprite 2 1194 27549696
Removing Sprite 2, s2 = null
Sprite 1 1204 27566080
Sprite 2 1204 27566080
Sprite 1 1214 27582464
Sprite 2 1214 27582464
Sprite 1 1224 27594752
Sprite 2 1224 27594752
Sprite 1 1234 27615232
Sprite 2 1234 27615232
Sprite 1 1243 27627520
Sprite 2 1243 27627520
Sprite 1 1253 27656192
Sprite 2 1253 27656192
Sprite 1 1263 27668480
Sprite 2 1263 27668480
Sprite 1 1273 27684864
Sprite 2 1273 27684864
Sprite 1 1283 27705344
Sprite 2 1283 27705344
Sprite 1 1293 27721728
Sprite 2 1293 27721728
Sprite 1 1302 27742208
Sprite 2 1302 27742208
Sprite 1 1312 27758592
Sprite 2 1312 27758592
Sprite 1 1322 27770880
Sprite 2 1322 27770880
Sprite 1 1332 27791360
Sprite 2 1332 27791360
Sprite 1 1342 27807744
Sprite 2 1342 27807744
Sprite 1 1352 27824128
Sprite 2 1352 27824128
Sprite 1 1361 27840512
Sprite 2 1361 27840512
Sprite 1 1371 27852800
Sprite 2 1371 27852800
Sprite 1 1381 27877376
Sprite 2 1381 27877376
Sprite 1 1391 27893760
Sprite 2 1391 27893760
Sprite 1 1401 27914240
Sprite 2 1401 27914240
Sprite 1 1411 27926528
Sprite 2 1411 27926528
Sprite 1 1421 27955200
Sprite 2 1421 27955200
Sprite 1 1430 27975680
Sprite 2 1430 27975680
Sprite 1 1440 27983872
Sprite 2 1440 27983872
Sprite 1 1450 28004352
Sprite 2 1450 28004352
Sprite 1 1460 28020736
Sprite 2 1460 28020736
Sprite 1 1470 28041216
Sprite 2 1470 28041216
Sprite 1 1480 28057600
Sprite 2 1480 28057600
Sprite 1 1489 28073984
Sprite 2 1489 28073984
Sprite 1 1499 28094464
Sprite 2 1499 28094464
Sprite 1 1509 28114944
Sprite 2 1509 28114944
Sprite 1 1519 28127232
Sprite 2 1519 28127232
Sprite 1 1529 28147712
Sprite 2 1529 28147712
Sprite 1 1539 28164096
Sprite 2 1539 28164096
Sprite 1 1547 28176384
Sprite 2 1547 28176384
Sprite 1 1557 28192768
Sprite 2 1557 28192768
Sprite 1 1567 28217344
Sprite 2 1567 28217344
Sprite 1 1577 28229632
Sprite 2 1577 28229632
Sprite 1 1587 28241920
Sprite 2 1587 28241920
Sprite 1 1596 27361280
Sprite 1 1605 27369472
Sprite 1 1614 27377664
Sprite 1 1624 27389952
Sprite 1 1634 27402240
Sprite 1 1644 27418624
Sprite 1 1654 27430912

Разумеется, трейс зависит от частоты кадров (при FPS 120, отставание 10%), и не передает ральные значения таймера.

gloomyBrain 20.06.2011 16:34

@S-ed
когда Вы делаете
Код AS3:

s1.addEventListener(Event.ENTER_FRAME, enterFrameListener);

Вы создаете у s1 ссылку на того, кому принадлежит метод enterFrameListener. То есть, s1 теперь уведомит кого-то, что у него (s1) произошло событие ENTER_FRAME и он (s1) вызовет у этого кого-то метод enterFrameListener и передаст в него соответствующий событийный объект.
Если бы мы написали вот так
Код AS3:

s1.addEventListener(Event.ENTER_FRAME, enterFrameListener, 123, true);

То владелец метода enterFrameListener может быть скушан GC, если на него нет никаких ссылок, кроме той самой, по которой s1 вызывает метод. К самому s1 это никакого отношения не имеет

etc 20.06.2011 16:47

S-ed, если ваш код скопипастить без изменений, никакого удаления Sprite 2 из памяти не будет. Если у вас вдруг пропал трейс с Sprite 2, при этом код не меняли — у вас битая память компьютера или кривой Flash Player.

S-ed 20.06.2011 16:56

gloomyBrain
Да, я знаю как это работает.
О, заодно вопрос, как защитить documentClass от сборки? На него как раз, как Вы сказали, нет ссылок...или он не собирается?

etc
Вот в том и дело, что у меня на 2х машинах "битая память". >_<

etc 20.06.2011 17:02

А, пардон, всё верно, GC работает, на s2 ссылок нет.

gloomyBrain 20.06.2011 17:16

Цитата:

или он не собирается
Ну, пока он есть в дисплей листе - нет, не собирается. Ведь его можно получить через getChildAt(). Это правило действует для всех, основной класс не является чем-то особенным

S-ed 20.06.2011 18:12

gloomyBrain
Понятно. У меня как раз его нет в дисплей листе (в том который проверял на GC).

А как его туда добавить? Ведь документКласс должен быть чайлдом чего-то...

dimarik 20.06.2011 21:43

Добавьте, addChild ) Jul 2001 это сильно!

S-ed 21.06.2011 01:29

dimarik
Я тупил. Добрый человек, подсказал.
ЧТО НАДО СОХРАНЯТЬ AS ФАЙЛЫ ПЕРЕД КОМПИЛЯЦИЕЙ!
Я как дятел половину кода проверял без сохранения (приучен студией).
Document Class нельзя добавить как addChild,- просто некуда. (как мне популярно объяснили, он сам добавляется в дисплей лист)

Дата? Да. Раньше хотел изучить, да все никак...
Теперь вот все с нуля учу, бо AS3 совсем другой.

gloomyBrain 21.06.2011 11:40

А Вы чем собираете? FlashDevelop сам все сохраняет перед сборкой (да все что угодно, кроме Flash IDE)

goodguy 21.06.2011 12:03

Цитата:

Ну. Проверьте код.
У меня работает. На CS4 и CS5.
тем, что как раз сохранять автоматом не умеет

dimarik 21.06.2011 12:18

Цитата:

Сообщение от S-ed (Сообщение 1005257)
Document Class нельзя добавить как addChild,- просто некуда. (как мне популярно объяснили, он сам добавляется в дисплей лист)

Да, он добавляется на Stage автоматом при запуске swf. Он является content'ом у Loader. Однако его можно перемещать по дереву списка отображения. Никто, кроме, возможно, политики безопасности вам слова не скажет. Это так, к слову.

S-ed 22.06.2011 00:16

gloomyBrain
ИДЕ собирал. FD только начал осваивать, жаль не имеет своего компилятора.

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

dimarik
Тоесть его можно опустить ниже по дереву? Или поднять выше из лоадера?


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

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