Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Flex (http://www.flasher.ru/forum/forumdisplay.php?f=84)
-   -   Адресация обьектов во Flex (http://www.flasher.ru/forum/showthread.php?t=110701)

LexeY4eg 07.04.2008 15:20

Адресация обьектов во Flex
 
Всем привет!

Не для кого не секрет что обьекты во Flex передаются в методы по ссылке на адрес в памяти. Но я был удивлен когда проделал следующее:

1. я создаю обьект, например var obj:Object = new Object();

также я написал метод примерно следующего содержания:

function updateObj(obj:Object) {
obj = new Object();
}

например до вызова метода у обьекта obj адрес в памяти 55555555. Затем я вызываю метод updateObj и передаю туда свой обьект, внутри метода obj начинает ссылаться на другой, толькочто созданный обьект в памяти, например его адрес 333333333. НО, по выходу из метода, obj продолжает ссылаться на 55555555!

Может ктонибудь прояснить это явление?
И как сделать, чтобы этого не происходило???

FlexOkeks 07.04.2008 16:59

Вы наверно путаете адрес объекта с адресом переменной которая хранит адрес объекта? obj это же не есть объект, это есть переменная и адрес у нее свой а объект как таковой будет new Object() и при каждом вызове будет создаваться новый объект с новым адресом, а адрес переменной obj создается когда вы объявляете var obj и что бы вы туда не присвоили адрес переменной obj останется прежним.

LexeY4eg 07.04.2008 18:29

Возможно я некорректно сформулировал вопрос, приведу небольшой пример:

Код:

        public class ObjTest
        {
                private var obj1:Object = new Object();
               
                public function test():void {
                        var obj2:Object = new Object();
                        trace(obj2); //b1
                        updateReference(obj2);
                        trace(obj2);//b4
                }
               
                private function updateReference(obj2:Object):void {
                        trace(obj1);//b2
                        obj2 = obj1;
                        trace(obj2);//b3
                }
               
        }

я установил во flexBuilder (незнаю как ещё можно посмотреть адрес обьекта в памяти) 4 брэкпоинта (я обозначил их коментами //b<n>), и получил следующий результат:

//b1 - obj2=@d01e6f1
//b2 - obj1=@d01e741
//b3 - obj2=@d01e741
//b4 - obj2=@d01e6f1 - почему тут снова @d01e6f1?

FlexOkeks 07.04.2008 21:49

Потому что это параметр, он опеделяется в скобках при вызове метода:
Код:

updateReference(obj2);
именно для того, чтобы внутри тела метода мы бы могли его прочитать. Поэтому оно опять тут снова. :)
Но откройте секрет, для чего же может понадобиться внесение таких недоразумений, как написали вы:
Код:

                private function updateReference(obj2:Object):void {
                        trace(obj1);//b2
                        obj2 = obj1;
                        trace(obj2);//b3
                }

, то есть, в первой части тела мы читаем одно значение obj2, а во второй части (если бы все происходило именно так как вы задумали) мы вообще теряем к нему доступ, то есть не сможем узнать чего передали в скопки при вызове метода, если не приложим дополнительных усилий для его сохранения оного в другой переменной? :eek: Это что, давняя привычка Штирлица уничтожать за собой все следы, от которой он не мог избавиться, и которая его постоянно я ставила его на грань провала? :cool:

LexeY4eg 07.04.2008 22:08

Вложений: 1
я всеголиш хочу, чтобы мой obj2 начал ссылаться на obj1. Я могу сделать это например вот-так:
Код:

        public class ObjTest
        {
                private var obj1:Object = new Object();
               
                public function test():void {
                        var obj2:Object = new Object();
                        obj2 = obj1;
                }
               
        }

но меня такой вариант не устраивает, мне нужно сделать это внутри метода.

Также прилогаю рисунок, который пояснит что я хочу сделать.

FlexOkeks 07.04.2008 22:15

Цитата:

Сообщение от LexeY4eg
я всеголиш хочу, чтобы мой obj2

Который из них? У вас их два: первый локальная переменная метода test() а второй параметр метода updateReference(obj2:Object) !

LexeY4eg 07.04.2008 22:26

Замечательно, уже ближе к истине.

я модифицирую пример:

Код:

        public class ObjTest
        {
                private var obj1:Object = new Object();
               
                public function test():void {
                        var obj2:Object = new Object();
                        trace(obj2); //b1
                        updateReference(obj2);
                        trace(obj2);//b4
                }
               
                private function updateReference(obj3:Object):void {
                        trace(obj1);//b2
                        obj3 = obj1;
                        trace(obj2);//b3
                }
               
        }

Теперь рисунок отображает то, что я хочу сделать. Я хочу чтобы obj2 и obj1 ссылались на одну ячейку в памяти.

FlexOkeks 07.04.2008 22:33

У вас obj2 живет только внутри метода test, если вы хотите, чтобы он был доступен в обоих методах, надо сделать его свойством, таким же как obj1
Код:

        public class ObjTest
        {
                private var obj1:Object = new Object();
                private var obj2:Object;
               
                public function test():void {
                        obj2 = new Object();
                        trace(obj2); //b1
                        updateReference();
                        trace(obj2);//b4
                }
               
                private function updateReference():void {
                        trace(obj1);//b2
                        obj2 = obj1;
                        trace(obj2);//b3
                }
               
        }


LexeY4eg 07.04.2008 22:46

Ок! я усовершенствовал свой пример, чтобы показать ради чего все это делается:

Код:

        public class ObjTest
        {
                private var obj1:Object = new Object();
                private var obj2:Object = new Object();
                private var array:ArrayCollection = new ArrayCollection();
               
                public function ObjTest() {
                        for (var i:Number = 0; i < 5; i ++) {
                                array.addItem(new Object());
                        }
                }
               
                public function test():void {
                        updateReference(obj2);
                        for each (var o:Object in array) {
                                updateReference(o);       
                        }
                }
               
                private function updateReference(obj:Object):void {
                        //тут у меня реализована сложная логика нахождения обьекта на который я хочу ссылаться
                        //и мне нехотелось бы дублировать ее в коде, поэтому я вынес ее в отдельный метод.
                        obj = obj1;
                }
               
        }

я добавил глобальный массив обьектов и глобальный обьект obj2. Я хочу чтобы все элементы массива а также obj2 начали ссылаться на obj1. Но, мне недостаточно просто выполнить присваивание, у меня есть какаято логика определения обьекта, на который я хочу ссылаться. Эту логику я вынес в отдельный метод, чтобы избежать дублирования кода. Вопрос остается прежний, как в данной ситуации заставить всех ссылаться на obj1.

etc 08.04.2008 10:58

Пример с обычным массивом:
Код:

for (var i:uint = 0;i < array.length;i++) {
    array[i] = obj1;
}

Вы передаете ссылку в свою функцию, в функции это уже новая локальная переменная, потом изменяете значение локальной переменной функции на новое. Но эта локальная переменная никакого отношения к массиву не имеет, разве изначально ссылается на некий объект, находящийся в неизвестном массиве.
Если очень хочется, можете написать так (опять же, если array — Array обычный):

Код:

private function updateReference(obj:Object):void {
                        array[array.indexOf(obj)] = obj1;
                }


LexeY4eg 08.04.2008 13:12

Спасибо за ответы.


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

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