Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Обнуление при конверсии типов. (http://www.flasher.ru/forum/showthread.php?t=205583)

Fogflasher 10.12.2013 14:20

Обнуление при конверсии типов.
 
Есть следующая функция:

Код AS3:

public static function playInto(mc:DisplayObjectContainer):void 
{
var cont:MovieClip = mc as MovieClip;
trace("mc = ", mc, mc.name);
trace("cont = ", cont, cont.name);
}

Первый трэйс отрабатывает нормально (значит в функцию приходит не null).
А вот второй выдает ошибку:
Цитата:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
Если перепрописать первую строчку вот так:
Код AS3:

var cont:MovieClip = MovieClip(mc);

То возникает другая ошибка:
Цитата:

TypeError: Error #1034: Type Coercion failed: cannot convert Clip_container@2df5401 to flash.display.MovieClip.
И как же это понимать, выходит нельзя что-ли вообще конвертировать DOC в MovieClip. Или может быть специфика какая-то влияет.

Akopalipsis 10.12.2013 14:27

Вообще у меня Ваш код работает. Возможно ошибка из-за обращения в статическом методе к не статическим свойствам...
Код AS3:

package 
{
        import flash.display.DisplayObjectContainer;
        import flash.display.MovieClip;
        import flash.display.Sprite;
 
        public class DOCTest extends Sprite
        {
                private var test:String = 'test';
                public function DOCTest()
                {
                        var mc:MovieClip = new MovieClip();
                        mc.name = 'mc';
                        DOCTest.test(mc);
                }
                private static function test(doc:DisplayObjectContainer):void
                {
                        var mc:MovieClip = doc as MovieClip;
                        trace(mc.name);//mc
                }
        }
 
}


Fogflasher 10.12.2013 14:50

Но у вас mc изначально MovieClip, это может влиять на успешность, наверное.
А у меня ссылка на объект которая прилетает в функцию, и ссылка, скорее всего, указывает на объект DOC.

Хотя, точно не знаю.
Объект, который "прилетает" в функцию - это экземпляр класса, который расширяет Sprite.
Я вообще думал у него тип Sprite (ну или MovieClip).

А похоже... стоп, а почему я решил, что это DOC, может это и правда DC...
Можно ли кстати как-то определить на лету, "чьим наследником" является данный объект?
Он так и остается Sprite? Или типность может считатся и как-то иначе, вверх по иерархии уходя.

Wolsh 10.12.2013 14:53

Цитата:

Вообще у меня Ваш код работает
Ну так если мувиклип передавать, то конечно))) Автор же видимо считает что можно любой контейнер ПЕРЕДЕЛАТЬ в МувиКлип.
Во-первых, as это не конверсия а кастинг, то есть "проба на роль". Возвращается null, если испытуемый не может играть роль, то есть не является сам и не содержит в цепочке наследования нужный класс. При этом не выбрасывается исключение (не генерится ошибка, Error). Ваш Error не при кастинге, а при попытке вызвать у null методы, которых у него нет.
Конверсия это MovieClip(mc). Если конверсия невозможна (по тем же причинам что и выше), то выбрасывается исключение "несоответствие типов". Вообще, никакого волшебного преобразования одного типа в другой нет, если Вы на такое надеялись. Не сделать МувиКлип из других классов. И кастинг, и конверсия в итоге говорят только "можно рассматривать данный экземпляр как экземпляр класса МувиКлип". Но с самим объектом, естественно, ничего при этом не происходит.

Akopalipsis 10.12.2013 14:54

Код AS3:

package
{
        import flash.display.DisplayObject;
        import flash.display.DisplayObjectContainer;
        import flash.display.MovieClip;
        import flash.display.Sprite;
 
        public class DOCTest extends Sprite
        {
                private var test:String = 'test';
                public function DOCTest()
                {
                        var mc:MovieClip = new MovieClip();
                        var sprite:Sprite = new Sprite();
                        DOCTest.test(mc);
                        DOCTest.test(sprite);
                }
                private static function test(target:DisplayObject):void
                {
                        if (target is MovieClip)
                        {
                                var mc:MovieClip = target as MovieClip;
                        }else if (target is Sprite)
                        {
                                var sprite:Sprite = target as Sprite;
                        }
                }
        }
 
}


Wolsh 10.12.2013 15:03

Akopalipsis, (исправьте "doc" на "target"), и что дальше с этим делать?
if (mc != null)... if (sprite != null)
так что-ли? А сразу нельзя было?))

Fogflasher 10.12.2013 15:04

Wolsh, интересно, спасибо за разьяснения.
Не знал что это всего лишь роль, думал флэш насильно трансмутирует объект, засовывая его в прокрустово ложе.

Akopalipsis, да точно, можно же и так, а то я уже было полез искать хитрые методы идентификации класса.
Добавил такой блок проверки:
Код AS3:

if (mc is MovieClip)
                        {
                                trace("is MovieClip");
                        }
                        else if (mc is DisplayObject)
                        {
                                trace("is DisplayObject");
                        }
                        else if (mc is DisplayObjectContainer)
                        {
                                trace("is DisplayObjectContainer");
                        }
                        else if (mc is Sprite)
                        {
                                trace("is Sprite");
                        }
                        else
                        {
                                trace("Holly crap!");
                        }

И получилось, что это DisplayObject.
Вы были правы в первом (удаленном) камменте.

А вот почему так..?
Он же extends Sprite. Или все объекты, которые попали в список отображения, автоматически меняют типа на DisplayObject?

strangedk 10.12.2013 15:05

Помнится, однажды у меня были проблемы при попытке конвертировать экспортированный MovieClip в собственно MovieClip. Ругался на несовместимость типов и всё тут.

Точно не вспомню как порешалось, но была обнаружена странность: Flash считал что MovieClip с одним кадром это Sprite.

Использовался и Flash Builder (для кастинга) и Flash CS (для экспорта swf).

Akopalipsis 10.12.2013 15:12

Цитата:

и что дальше с этим делать?
Вот тут я не понял... Если в методе ожидать конкретно mc, то да, можно сделать как Вы написали - if (mc != null). Но скорее всего в методе ожидаются любые классы, которые нужно присвоить на некоторое время какой то переменной и для этого нужно проверить лишь принадлежность к MC либо Sprite. Ну или в крайнем случаи if (target is MovieClip&&target!=null)

Fogflasher 10.12.2013 15:13

strangedk, кстати у меня похожий случай. (Использую пока только Flash IDE, к слову).

Этой функции передается объект, класс которого в библиотеке создан как MovieClip.
Но он имеет один кадр, и я для него написал еще и кустомный класс, в котором много всего.
Внутри этого кустомного класса, он кстати расширяет Sprite, что... является наверное некоторым косячком : ))
Возможно не стоило вообще ему extends дописывать, ведь в библиотеке этот extends (если я всё правильно понимаю) уже назначен на MovieClip.


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

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