PDA

Просмотр полной версии : Singleton, время инициализации статической константы


lubko
22.06.2012, 14:23
Не могу понять, почему _arr2==null?
Объясните, пожалуйста.


var sg:Singleton = Singleton._instance;
trace(sg.arr1);
trace(sg.arr2);



public class Singleton
{
public static const ARR1:Array = [1, 2, 3];
public static const _instance = new Singleton();
public static const ARR2:Array = [3, 2, 1];

private var _arr1:Array = ARR1;
private var _arr2:Array = ARR2;

public function Singleton()
{
if (_instance)
throw new Error("Class is singleton.");
}

public function get arr1():Array { return _arr1; }
public function get arr2():Array { return _arr2; }
}



1,2,3
null

strangedk
22.06.2012, 14:33
У вас реализация синглтона неправильная.

Плюс к тому же непонятны операции между статическими и обычными переменными.

Сделайте так, и увидите разницу:

trace(Singleton.ARR1); // 1,2,3
trace(Singleton.ARR2); // 3,2,1

lubko
22.06.2012, 16:46
если поставить брейкпоинт на строке
private var _arr2:Array = ARR2;
будет видно что статическая константа ARR1 уже проинициализирована, а ARR2 все еще равна null.
поэтому в _arr2 попадает null.
переменные _arr1 и _arr2 нужны были лишь чтобы показать это.

Jewelz
22.06.2012, 16:54
а так?

public static const ARR1:Array = [1, 2, 3];
public static const ARR2:Array = [3, 2, 1];
public static const _instance = new Singleton();

FlashRus
22.06.2012, 17:10
http://ru.wikipedia.org/wiki/Одиночка_(шаблон_проектирования)

lubko
22.06.2012, 17:34
а так?


public static const ARR1:Array = [1, 2, 3];
public static const ARR2:Array = [3, 2, 1];
public static const _instance = new Singleton();

так все ОК. в _arr2 попадет значение ARR2.

но кто-нибудь может ответить почему ARR2==null на указаной строчке

public class Singleton
{
public static const ARR1:Array = [1, 2, 3];
public static const _instance = new Singleton();
public static const ARR2:Array = [3, 2, 1];

private var _arr1:Array = ARR1;
private var _arr2:Array = ARR2; // breakpoint!!!! здесь ARR2==0, a ARR1== [1, 2, 3]

}

Hauts
22.06.2012, 17:41
Вероятно потому, что инициализация приватных полей происходит во время создания класса, а на этот момент ARR2 не существует.

lubko
22.06.2012, 17:42
http://ru.wikipedia.org/wiki/Одиночка_(шаблон_проектирования)

вот код с вики:

public class Singleton
{
public static const instance:Singleton= new Singleton;

public function Singleton()
{
// Boolean(Singleton) is false when creating instance before static constructor executed.
if(Singleton) throw new Error("Class is singleton.");
}

}


вот мой:

public class Singleton
{
public static const _instance = new Singleton();
public function Singleton()
{
if (_instance)
throw new Error("Class is singleton.");
}
}

вроде не сильно отличается, только я проверяю _instance.
не совсем понимаю что значит эта проверка if(Singleton).
но это вроде другой вопрос. хотя тоже интересно

Добавлено через 4 минуты
Вероятно потому, что инициализация приватных полей происходит во время создания класса, а на этот момент ARR2 не существует.

похоже на правду. скажите где можно почитать про такие вещи подробней?
спасибо

Hauts
22.06.2012, 17:51
1. скажите где можно почитать про такие вещи подробней? — на flasher.ru.
2. if(Singleton) throw new Error("Class is singleton.");
На момент создания статичного поля "instance" Singleton`а не существует (хотя наверное не класса, а функции-конструктроа), судя по комментарию. А вот в конструкторе синглетона Boolean(Singleton) вернет true, потому, что он уже существует. Довольно неочевидное явление :)

strangedk
22.06.2012, 18:02
lubko, Просто не делайте так, и не возникнет таких вопросов.
Зачем вам в одном классе статические переменные класса, поля объекта и геттеры?

Создайте один класс с данными, и напичкайте его статическими данными, и потом обращайтесь в синглтоне к нему. Зачем так всё путать.

lubko
22.06.2012, 18:13
всем спасибо. Тема закрыта

a_[w]
22.06.2012, 18:36
Потому что весь код класса, включая и статические переменные выполняются/инициализируются во время первого использования класса, по порядку. А у вас первое использование класса происходит между ARR1 и ARR2(ARR1, конструктор, ARR2, getInstance), поэтому получается ARR1 уже проинициализиорован, а ARR2 ещё нет. Если вы каким-то образом создадите второй экземпляр "синглтона", то у него уже всё будет впорядке.

function getInstance(){
if(!_instance) _instance = new Singleton(); // выполнится после всех инициализаций уровня класса
return _instance;
}