Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Экземпляр, созданный при объявлении статического свойства не видит других классов (http://www.flasher.ru/forum/showthread.php?t=99465)

Ромастый 06.08.2007 19:45

Экземпляр, созданный при объявлении статического свойства не видит других классов
 
Столкнулся со следующей штукой.
Код:

class MyClass {
        static var ref = new MyClass("from class MyClass: ");
        function MyClass(from) {
                var from=from? from : "from outside:"
                trace(from+"  "+mx.events.EventDispatcher);
        }
}

во fla:
Код:

myClass = new MyClass();
//from class MyClass:  undefined
//from outside:  [type Function]

При создании экземпляра класса через объявление статического свойства класса экземпляр не видит других пользовательских классов.
(С тем же успехом вместо mx.events.EventDispatcher можно написать mx.utils.Delegate)
Однако
Код:

class MyOtherClass extends MyClass {
        static var ref = new MyOtherClass("from class MyOtherClass extends MyClass: ");
        function MyOtherClass(from) {
                super(from)
        }
}

Код:

myOtherClass = new MyOtherClass();
//from class MyClass:  [type Function]
//from class MyOtherClass extends MyClass:  [type Function]
//from outside:  [type Function]

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

Кроме того, если в MyClass заменить EventDispatcher на какой-либо из документированных классов (XML или скажем BitmapData) - тоже все нормально работает.
В чем тут дело? Особый порядок инициализации классов?

etc 06.08.2007 20:04

Для начала неплохо было бы все-таки написать import.

Ромастый 06.08.2007 20:12

Цитата:

Сообщение от __etc
Для начала неплохо было бы все-таки написать import.

А без разницы. В AS2 директива import используется только для сокращения полных имен классов.
Но даже если написать import
Код:

import mx.events.EventDispatcher;
class MyClass {
        static var ref = new MyClass("from class MyClass: ");
        function MyClass(from) {
                var from=from? from : "from outside:"
                trace(from+"  "+EventDispatcher);
        }
}

флэш все равно выдаст from class MyClass: undefined
Ессно проверял, перед тем как постить.

etc 06.08.2007 20:19

Да-да-да. Заплатка:

Код:

import mx.events.EventDispatcher;
class MyClass {
        private static var __dummy:EventDispatcher = EventDispatcher;
        public static var instance:Object = new MyClass("static");
        public function MyClass(str:String) {
                trace(str+':'+EventDispatcher);
        }
}

Что и как расскажу потом, ибо домой надо бежать.

Ромастый 06.08.2007 20:30

Цитата:

Сообщение от __etc
Да-да-да. Заплатка

Мда, не сообразил... :confused:
Спасиб! :)

P.S. Раз речь идет о заплатке, как я понял - очередные грабли?

Kikasso 06.08.2007 21:17

У меня FDT вообще не дает объявлять непростые типы вне функций.
Грабли в том, что например вы пишете
Код:

static var ref = new MyClass("from class MyClass: ");
а попробуйте написать так:
Код:

var ref = new MyClass("from class MyClass: ");
Знайте, что ref во втором случае тоже будет статичным.

Ромастый 06.08.2007 21:56

Цитата:

Сообщение от Kikasso
а попробуйте написать так:
Код:

var ref = new MyClass("from class MyClass: ");
Знайте, что ref во втором случае тоже будет статичным.

Очень спорно. Поясню:
1.Если так писать при объявлении свойства - будет белиберда.
2.Если ref объявить как static, а значение присваивать в конструкторе, то оно ессно будет статическим, вот только каждый раз это будет новый объект.:away:
3.Единственно что в таком варианте сработает - это написать отдельный метод, который создает экземпляр MyClass и делает ref ссылкой на него, после чего вызывать это метод единожды.
А вопрос был собственно о создании экземпляра в объявлении свойств.
__etc дал ответ в точку.

etc 06.08.2007 22:56

Вообще говоря, лучше применять паттерн синглтон и не работать со статической ссылкой напрямую.

А заплатка… да, заплатка, потому что компилятор инициализирует все, кроме тел методов, в итоге он просто не догадывается, что EventDispatcher нужно инициализировать раньше MyClass.

Ромастый 07.08.2007 01:57

Вот собсно необходимость такой заплатки и интересовала - почему флэш в данном случае прекрасно видит документированные классы (вроде той же BitmadDatы), но не инициализирует пользовательские?
Напрашивается только один ответ.

Что касается синглтона... Если интересно, могу рассказать.
Есть дерево классов с бесконечным количеством дочерних классов (теоретически, практически же 5-10 уровней наследования, но сути не меняет).
Статические(!) свойства любого из классов могут меняться по событию,
И все экземпляры этого класса, а также экземпляры расширяющих этот класс, должны тут же отреагировать.
Собственно, синглтон я сразу же и использовал - подписывать все экземпляры дочернего класса на его синглтон, а синглтон дочернего в свою очередь на синглтон родительского.
Вот только одна проблема: при расширении синглтона метод getInstance в дочернем классе каждый раз надо оверрайдить. Учитывая 5-10 уровней наследования и около 200-300 классов, картинка получается жестковата, даже несмотря на то, что as-файлы будут генериться каким-нить ming'ом... В общем захотелось схалявить, и сделать это одной строчкой - через объявление статического свойства и присвоение ему экземпляра.
Если есть другие решения - буду рад узнать :)

Kikasso 07.08.2007 02:34

Я собственно другой глюк имел в виду.
as
Код:


class Test{
 public static var arr:Array = [];
 public var arr2:Array = [];
 public var id:String;
 public function Test( id:String ){
  arr.push( this );
  arr2.push(this); 
  this.id = id; 
  }
 public function toString():String{
 return 'Test '+ id;
 } 
}

fla
Код:


 
import Test;
var t1:Test = new Test('t1');
var t2:Test = new Test('t2');
trace( Test.arr );
trace('----------');
trace( t1.arr2 );
trace('----------');
trace( t2.arr2 );
trace('----------');

trace
Код:


Test t1,Test t2
----------
Test t1,Test t2
----------
Test t1,Test t2
----------

Попытка оттрейсить Test.arr2 вызовет ошибку - то есть свойство как бы не статичное.
А по вашему вопросу - можно так:
as
Код:

class Test{
public static var ref:Test = Test.createRef();
public var id:String;
public static function createRef():Test{
        trace('ссылка создана');
        return new Test('etalon');
}
public function Test( id:String ){
        this.id = id;
}
public function toString():String{
        return 'Test '+ id;
}               
}

fla
Код:

import Test;
var t1:Test = new Test('t1');
trace( Test.ref );
var t2:Test = new Test('t2');
trace( Test.ref );

P.S. что такое синглтон, сорри, не знаю. Гуглить лень.


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

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