PDA

Просмотр полной версии : Объекты и "дети"


GknTnm
26.12.2012, 11:32
День добрый,
Господа объясните в чем различие между:

this.addChild(new Symbol1());

и

var smb:Symbol1 = new Symbol1();
this.addChild(smb);

а также как правильно удалить созданный объект в обоих случаях?

iNils
26.12.2012, 13:11
Тем, что во втором случае создается временная ссылка на объект, что позволит с объектом что-то сделать, например задать другие координаты, или сменить уровень прозрачности.

Удалить в первом случаи объект может быть проблематично, так как не известно, он один там или несколько. Если один, то просто
removeChildeAt (0)
Если несколько и удалить нужно конкретный объект, то не имея на него ссылки, индекса глубины или имени, не получится. Поэтому, используя второй вариант, можно сохранить ссылку на объект (например в переменной класса, а не в локальной как сейчас, или в массиве) и потом по ней удалить.
removeChild (ссылка)

GknTnm
26.12.2012, 16:35
Спасибо за ответ.

Просто пытаюсь написать "менеджер объектов" и хочется сделать это красиво.

т.е. строкой
var smb:Symbol1 = new Symbol1();
мы всего лишь указываем что smb будет хранить ссылку на объект, а не сам объект.

возможно ли создать объект который не будет иметь на себя ссылки и не быть чьим либо потомком?
я так понимаю возможно:
var smb:Symbol1 = new Symbol1();
smb = null;
тогда как потом его удалить?

и далее:
попробовал контролировать объекты в сцене следующим образом, создал класс Global.as и создал в нем массив Unit:


package {

public class Global {

public static var Unit:Object = [];

public function Global() {
// constructor code
}

}

}


основному клипу сделал класс main.as


package {

import flash.display.MovieClip;

import Global;


public class main extends MovieClip {


public function main() {
// constructor code
Global.Unit[0] = new Symbol1();
Global.Unit[1] = new Symbol1();
Global.Unit[2] = new Symbol1();

//первый
trace(Global.Unit[0].numChildren, Global.Unit[2].numChildren);
//1 1

this.addChild(Global.Unit[0]);
Global.Unit[0].addChild(Global.Unit[1]);

//второй
trace(Global.Unit[0].numChildren, Global.Unit[2].numChildren);
//2 1



this.addChild(Global.Unit[2]);
Global.Unit[2].addChild(Global.Unit[1]);

//третий
trace(Global.Unit[0].numChildren, Global.Unit[2].numChildren);
// 1 2


Global.Unit[1].parent.removeChild(Global.Unit[1]);
Global.Unit.splice(1,1);



}
}

}



и сразу возникли вопросы:

первый trace возвращает "1 1"? кто эти дети?

второй и третий trace меня порадовали - т.е. родитель знает сколько у него детей даже если вдруг его ребенку назначить другого родителя он это отследит. Всегда так, или возможны исключения?

Правильно ли удалять ребенка (из любого места и даже другого класса если ему (другому классу) также импортировать Global) следующим образом:


Global.Unit[1].parent.removeChild(Global.Unit[1]); //удаляем объект
Global.Unit.splice(1,1); //удаляем ссылку на него


?

или есть более элегантный метод удаления объектов?

TanaTiX
26.12.2012, 16:54
тогда как потом его удалить?
Если на объект не остается ссылок, то он удаляется GC-ом.
Правильно ли удалять ребенка (из любого места и даже другого класса
Нет. Детей должны убивать родители. Глобальный доступ - источник ошибок и каши в любом проекте.

Psycho Tiger
26.12.2012, 17:18
Ребёнок просит родителя его удалить, а родитель уже решает, удалять его, или не удалять. Ребёнку, в целом, глубоко пофигу где лежать.
Просить родителя хорошо событием. EventDispatcher#dispatchEvent.

Ещё рекоммендую пользоватья ссылками на полную катушку.
Например, вместо
trace(Global.Unit[0].numChildren, Global.Unit[2].numChildren);
вот так
var units:Array = Global.Unit;
units[0].nimChildren, units[2].numChildren
или ещё лучше
var units:Array = Global.Unit;
var firstUnit:DisplayObjectContainer = units[0];
var secondUnit:DisplayObjectContainer = units[2];
firstUnit.numChildren, secondUnit.numChildren;