Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Правильно обработать IOErrorEvent, чтоб замолчал (http://www.flasher.ru/forum/showthread.php?t=183692)

zerAlex2 29.08.2012 14:35

Правильно обработать IOErrorEvent, чтоб замолчал
 
Как правильно обработать ошибку IOErrorEvent? У меня если картинка не найдена, то просто подставляется текст в кнопке, но постоянно вылазит ошибка, что IOErrorEvent не обрабоан.
Код AS3:

private function loadImg():void
{
 loader=new Loader();
 var Request:URLRequest = new URLRequest("my.jpg");
 loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadImg);
 loader.contentLoaderInfo.addEventListener (IOErrorEvent.IO_ERROR, errorHandler);
 loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
 loader.load(Request);
}
 
private function errorHandler(e:IOErrorEvent):void
{
 //Сюда он программа, но и меняет текст на кнопке, но выскакивает ошибка
 loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoadImg);
 loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
 loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
 loader=null;
 loaderError=true;
 this.errorText.text=noPicEng;
}
 
private function onLoadImg(e:Event):void
{                       
 
 loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoadImg);
 loader.contentLoaderInfo.removeEventListener (IOErrorEvent.IO_ERROR, errorHandler);
 loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
 this.img.addChild(loader);
}

Код:

Error #2044: Необработанный IOErrorEvent:. text=Error #2035: URL-адрес не обнаружен.

bav 29.08.2012 15:01

Единственная неточность, которую я здесь наблюдаю, это то что вы слушателем события SecurityErrorEvent.SECURITY_ERROR задаете функцию, параметром которой выступает переменная IOErrorEvent. Может в этом дело? А вот эта строчка выполняется?
Код AS3:

this.errorText.text=noPicEng;

Могу еще предположить, что после того как вы удалили слушатель IOErrorEvent, событие возникает еще раз (по какой-то причине) и уже, соответственно, не обрабатывается.

P.S. ""Сюда он программа" – это да.

Wolsh 29.08.2012 15:10

Тоже думаю, что дело в отписках по одному событию от всех скопом.

zerAlex2 29.08.2012 15:14

Всё работает, текст меняется, дальше трейсится, но выскакивает ошибка.
Добавил функци, чтоб обрабатывала SecurityErrorEvent.

Да, верно. Закоментировал removeEventListener-ы и всё прошло ) А как же быть. Отписаться-то надо бы.

Ругается на
Код AS3:

loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);

Но если строчку затереть и оставить другие, то:
Код:

TypeError: Error #1009: Не удается вызвать свойство или метод со ссылкой на объект "null".
        at com::IPrj_Button/errorHandler()

А если я делаю loader=null, мусорщик подберёт эти EventListener-ы?

maxkar 29.08.2012 15:23

У вас loader локален для loadImg. Удалите там объявление и используйте глобальный лоадер (к которому обращение в errorHandler).

Wolsh 29.08.2012 15:38

Цитата:

У вас loader локален для loadImg.
Почему локален? Объявления переменной то нет. Она объявлена в теле класса, видимо. Просто товарищ не пишет прочерк перед приватами))
Цитата:

А если я делаю loader=null, мусорщик подберёт эти EventListener-ы?
Не путайте местами. Вы лоадер зануляете, а не this. Листенеры добавили в лоадер ссылки на this, а не наоборот.

zerAlex2 29.08.2012 16:50

Код AS3:

private var loader                        :Loader;

Он объявлен. Просто там кусочек, который грузит картинку в конкретную кнопку.

Цитата:

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

Wolsh 29.08.2012 20:29

Цитата:

т.е., если я грохну кнопку, что всё занулится?
)) Вы правда думаете, что я видел вашу кнопку в спиритическом сеансе? У меня еще нет черного пояса по астральному карате.
Просто Ваш вопрос упрямо намекает на весьма распространенное заблуждение "слышал звон..." про удаление листенеров перед удалением объекта.
Что такое object.addEventListener(event, handler)? Вы отдаете object'у ссылку на метод handler. И когда случится event, object просто вызовет этот метод handler, передав ему в параметр event. Но handler расположен не в object, а в другом месте (обычно в this, т.е. можно было бы писать this.handler. Таким образом, мы отдаем в object ссылку на this. Это означает, что пока жив object, мы не можем скормить GC this (владельца handler) — на него имеется ссылка. Но это никаким образом не мешает нам удалить object. Это часто путают.

zerAlex2 30.08.2012 04:09

Код AS3:

package {
 
        import flash.display.Sprite;
        import flash.events.*;
        import flash.net.URLRequest;
        import flash.display.Loader;
        import fl.text.TLFTextField;
        import flash.text.TextFormat;
        import flash.text.Font;
        import flash.text.TextFieldAutoSize;
        import flash.geom.Rectangle;
 
        import com.greensock.*;
        import com.greensock.plugins.*;
        import com.greensock.easing.*;
        import com.greensock.plugins.TintPlugin;
        import com.greensock.plugins.TweenPlugin;
 
        public class Prj_Button extends Sprite {
 
                public var prjNum                                :int;//Номер
                public var folder                                :String;//Папка               
 
                private var prjImg                                :String;
                private var loader                                :Loader;//Изображение
                private var loaderError                        :Boolean;//Ошибка лоадера
                private var noPicRus                        :String;
                private var noPicEng                        :String;               
                private var filePath                        :String;//Путь к файлу
 
                public function Prj_Button(lang:Boolean, fldr:String, prjN:int, img:String) {//
                        // constructor code
                        currentLang=lang;
                        folder=fldr;
                        prjNum=prjN;               
                        prjImg=img;
                        loaderError=false;
                        noPicRus="Изображение отсутствует";
                        noPicEng="No picture";
                        if (stage)
                        {
                                initButton();
                        }else{
                                this.addEventListener(Event.ADDED_TO_STAGE, onStageOk);
                        }
 
                }
 
                private function onStageOk(e:Event):void{
                        this.removeEventListener(Event.ADDED_TO_STAGE, onStageOk);
                        initButton();
                }
 
                private function initButton():void
                {
                        //Наполнить кнопку
                        loadImg();
                        this.mouseEnabled=true;
                        this.mouseChildren=false;
                }
 
                private function loadImg():void
                {
                        //Загрузить картинку
                        loader=new Loader();
                        var file:String="";
                        if (prjNum<10) file=file+"0";
                        if (prjNum<100) file=file+"0";
                        file=file+prjNum+".jpg";
                        filePath="data/"+folder+"/"+file;
                        var Request:URLRequest = new URLRequest(filePath);                       
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadImg);
                        loader.contentLoaderInfo.addEventListener (IOErrorEvent.IO_ERROR, errorHandler);
                        loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
                        loader.load(Request);
                }
 
                private function errorHandler(e:IOErrorEvent):void
                {                       
                        loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoadImg);
                        loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
                        loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
                        loader=null;
                        loaderError=true;
                        if (currentLang)
                        {
                                this.errorText.text=noPicRus;
                        }else{
                                this.errorText.text=noPicEng;
                        }
                }
 
                private function securityErrorHandler(e:SecurityErrorEvent):void
                {                       
                        loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoadImg);
                        loader.contentLoaderInfo.removeEventListener (IOErrorEvent.IO_ERROR, errorHandler);
                        loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
                        loader=null;
                        loaderError=true;
                        if (currentLang)
                        {
                                this.errorText.text=noPicRus;
                        }else{
                                this.errorText.text=noPicEng;
                        }
                }
 
                private function onLoadImg(e:Event):void
                {                       
                        //Подогнать изображение под размер и выровнять
                        loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoadImg);
                        loader.contentLoaderInfo.removeEventListener (IOErrorEvent.IO_ERROR, errorHandler);
                        loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
                        this.img.addChild(loader);
                        var maxWidth=276;
                        var maxHeight=216;
                        var mc:MovieClip=this.img;
                        var ratio:Number;
                        if (mc.height > mc.width)
                        {                               
                                ratio=maxWidth/mc.width;
                        }else{
                                ratio=maxHeight/mc.height;
                        }
                        mc.width*=ratio;
                        mc.height*=ratio;       
                        mc.x=-(mc.width-maxWidth)/2;
                }
 
        }//       
}//


Wolsh 30.08.2012 18:16

Если честно, я ничего не понял. Что такое Прж, и почему дальше Button, если это класс, загружающий картинк(у || и).. А дальше не настолько понятно, что происходит, чтобы критиковать. Единственное, неясно зачем было выносить initButton и onStageOk в два метода, а вот отписку от листенеров методично набивать несколько раз, вместо того чтобы вынести в метод removeListeners.. Зачем Request называется с большой, и что это за игры разума с prjNum и filePath.. Зачем вообще КНОПКА (если конечно это кнопка, не нашел мышиных событий в ней О__о) занимается загрузкой картинок, да еще и сама сочиняет, каких и откуда? И почему размеры какие-то жестко зашиты в коде..
Объясните контекст, в котором это чудо функционирует, любопытный механизм...


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

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