Всем привет! Пару дней сидел без интернета.
Цитата:
Сообщение от VitaliyKrivtsov
Если не вызвать принудительно GC, и подождать немножко пока сам запустится, то получим:
- loader удаляется если описаны от всех слушателей и e.target.loader.content не находится в списке отображения;
|
Верно только второе. Можно не отписывать loaderInfo. Второе верно только как следствие того, что опишу ниже.
Цитата:
|
- e.target.loader.content не находится в списке и без ссылки - тоже удаляется;
|
Логично.
Цитата:
|
- loader удаляется, если на e.target.loader.content есть ссылка, не находится в списке отображения, обнулен;
|
Неверно. Есть ссылка на content - Loader жив.
Цитата:
|
не удаляется loader, если не отписаться от слушателей;
|
Удаляется. Уже высказался.
Цитата:
|
не удаляется loader, если на e.target.loader.content была ссылка за пределами функции,
|
Тут я уже говорил. Если есть ссылка, неважно где: в пределах функции, метода или поля класса. Важно другое: пока она есть, значит она указывает на реальный живой объект,
Вышли мы из функции, ссылка пропала.
Цитата:
|
не удаляется loader, если e.target.loader.content находится в списке отображения но нет ссылки за пределами функции,
|
Верно. Ссылка в таком случае будет (stage._childList[N]...displayObjectContainer._childList[N] as DisplayObject).loaderInfo.loader;
Дальше расскажу что происходит с loader при загрузке растровых изображений (JPEG, PNG, GIF).
Эксперимент проводился с Adobe Flash Player 10.0 r45 debug. Результат исследований заставил задуматься.
Пока существует ссылка на BitmapData контента (loader.content as Bitmap).bitmapData, (loaderInfo.content as Bitmap).bitmapData, жив и лоадер.
Можно даже сделать ей dispose(), ничего не изменится. Скажу больше. Даже bitmapData.clone() не позволит удалиться лоадеру.
Однако после bitmapData.draw() GC может удалить Loader.
Код маленького эксперимента

Код AS3:
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011. Dimarik
//
///////////////////////////////////////////////////////////////////////////////
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.net.URLRequest;
/**
* @author Dimarik
* @version 1.0
* @langversion 3.0
* @playerversion 9.0
*
*/
[SWF(width="400", height="200", frameRate="21", backgroundColor="#E0EEEE")]
public class LoaderTest extends Sprite {
//-------------------------------------------------------------------------
//
// Constructor
//
//-------------------------------------------------------------------------
public function LoaderTest() {
super();
super.addEventListener(Event.ADDED_TO_STAGE, this.initialize);
}
//-------------------------------------------------------------------------
//
// Private methods
//
//-------------------------------------------------------------------------
private var _bitmapData: BitmapData;
//-------------------------------------------------------------------------
//
// Private methods
//
//-------------------------------------------------------------------------
public function initialize(event:Event):void {
(event.target as IEventDispatcher).removeEventListener(event.type, arguments.callee);
super.stage.scaleMode = StageScaleMode.NO_SCALE;
super.stage.align = StageAlign.TOP_LEFT;
var url: String = 'http://www.flasher.ru/forum/image.php?u=69797&dateline=1296252938';
var request: URLRequest = new URLRequest(url);
var loader: Loader = new Loader();
loader.load(request);
var li: LoaderInfo = loader.contentLoaderInfo;
li.addEventListener(Event.COMPLETE, this.handler_complete);
}
//-------------------------------------------------------------------------
//
// Events handlers
//
//-------------------------------------------------------------------------
/**
* @private
* В таком виде в методе не произойдет удаление Loader
*/
private function handler_complete(event:Event):void {
var li: LoaderInfo = event.target as LoaderInfo;
var loader: Loader = li.loader;
trace(li.contentType);
// Раскомментируйте, чтобы проверить, что отписывание не влияет на решение GC об удалении loader
//li.removeEventListener(Event.COMPLETE, this.handler_complete);
var bitmap: Bitmap = loader.content as Bitmap;
var bitmapData: BitmapData = bitmap.bitmapData;
// Дублирование исходной BitmapData не влияет на лоадер. Он будет жить.
var bitmapData2: BitmapData = bitmapData.clone();
// Однако draw не обладает такой силой.
// Раскомментируйте, чтобы проверить, что в этом случае лоадер будет удален
/*
var bitmapData2: BitmapData = new BitmapData(bitmapData.width, bitmapData.height);
bitmapData2.draw(bitmap);
*/
bitmap = new Bitmap(bitmapData2);
// Пока есть ссылка на bitmapData, лоадер не будет удален. Закомментируйте для удаления лоадера.
this._bitmapData = bitmapData2;
// Пока используется оригинальная bitmapData или раздупленная через clone() лоадер будет жить.
//super.addChild(bitmap);
loader.unloadAndStop();
}
}
}
Вывод. Если в аппдомене существует используемое растровое изображение (только не надо говорить, что изображение загружается не в аппдомен), то Loader, которым загрузили это изображение остается среди живых объектов и не удаляется.