![]() |
|
||||||||||
|
|||||
|
задался вот таким вопросом: "Если в приложение загружается изображение или мувик (не важно, что именно ) и после загрузки нужно удалить loader, то как правильно (если так можно выразится) удалить этот loader, что бы он не завис в памяти с концами". Почитал не много немало литературы по этой теме, в частности заглянул в книгу Мука, вообщем написано везде, что нужно удалить все ссылки на объект а потом обнулить, но как быть в случае, когда нужно, например, загрузить картинку а после удалить loader, но при этом у нас есть ссылка на битмап, удаляем все слушатели , обнуляем loader , выводи в трейс и получаем null, то есть то к чему стремились, но мне не до конца понятно, удалится из памяти сборщиком мусора loader или нет ? И, наверное, из-за того, что есть ссылка на одно из его свойств, а точнее на свойство contentLoaderInfo.
Вот кусок кода в пример: private function loadImage ( ):void { var loader:Loader = new Loader( ); loader.load( new URLRequest("1.jpg") ); loader.contentLoaderInfo.addEventListener( Event.INIT, initHandler ); } private function initHandler( e:Event ):void { var loader:Loader = Loader( e.target.loader ); var byteArray:ByteArray = ByteArray( e.target.bytes );// а вот и ссылка ) var bitmap:Bitmap = Bitmap( loader.content );// а вот еще одна ссылка ) // loader.contentLoaderInfo.removeEventListener( Event.INIT, initHandler ); loader = null;// равно теперь null } Последний раз редактировалось VitaliyKrivtsov; 27.01.2011 в 06:07. |
|
|||||
|
По идее лоадер должен удалиться при следующем вызове GC.
Грубо говоря, этот пример работает по тому же принципу: Вы некоторые данные сохранили по другим ссылкам, а объект и его свойства удаляются. |
|
|||||
|
.
|
Попытаюсь порассуждать.
Лоадер никуда не денется и GC не может его удалить. Bitmap, как DisplayObject, имеет ссылку на LoaderInfo, который содержит ссылку на Loader. Если загружать свф, то у всех его визуальных объектов будет ссылка на loaderInfo и, соответственно, loader. Т.о. пока существует хоть один визуальный объект, загруженный через данный Loader, экземпляр этого лоадера не будет уничтожен. Добавлено через 18 минут Не. Даже не так ) Пока существует ссылка на ApplicationDomain, в который лоадер загрузил классы, то будет существовать и сам лоадер. О, как! Кстати, так как картинка является экземпляром Bitmap класса без имени, то "выдернуть" ее класс непосредственно из ApplicationDomain и сделать еще один экземпляр не представляется возможным. Но это можно сделать через ссылку на конструктор BitmapData. В своих экспериментах с байткодом я загружал картинку, оборачивал ее бинарные данные в именованный класс и, вуаля! Имеем картинку, которую можно в любой момент инстанцировать по ApplicationDomain#getDefinition(). Добавлено через 1 час 22 минуты Если будет существовать корневой объект (ссылка DisplayObject#root указывает на него), то можно получить ссылки на loaderInfo и его loader. Для загруженных через Loader изображений корневым объектом является сам Bitmap. Опять же это говорит в пользу того, что loader не уничтожается. Последний раз редактировалось dimarik; 27.01.2011 в 11:58. |
|
|||||
|
не лоадер, а Кощей бессмертный получается. т.е. чтобы убить лоадер нужно сделать тройное сальто.
__________________
http://cleptoman.free-lance.ru achivements: дважды благословлен на воровство. осеяный благодатью |
|
|||||
|
olexandr, то есть, если ссылка на другой объект через свойство первого объекта сохраняется в другом объекте - первый будет удален из памяти.
Тогда в случае с loader, сам loader мог бы быть удален, а значение bitmap и byteArray сохранилось бы. Вернусь к Вашему примеру, а именно в второй строчке значение присваивается, но это не ссылка на arr[0], если я не ошибаюсь, arr должен удалится, а вот если это ссылка на одно из свойств объекта, то ссылка ведет на тот участок памяти в котором и есть наш объект по ссылке, и при следующем обращении к bitmap мы обращаемся напрямую к объекту типа данных Bitmap минуя loader и его свойство loaderInfo, и это значит, что loader может быть удален со своими свойствами сохраняя при этом bitmap, но тогда зачем такое удаление объекта, если все что с ним связано не удаляется полностью. Тогда вообще не понятно, что удаляется. Или удаляется, то что не было сохранено прежде по ссылке через loader, а все остальное прежде в памяти будет сидеть. Пожалуйста, уважаемые форумчане, укажите путь праведный. Я уже сам запутался и в одиночку не разберусь. olexandr, вот еще, если сделать вот так: var oneArray:Array = new Array("a", "b", "c"); var twoArray:Array = oneArray;// ссылка на oneArray oneArray = null; trace(twoArray); // Output: a, b, c, но мы же удалили oneArray, а значения twoArray выводятся так как // будто ничего и не происходило, oneArray хоть и был занулен, но так и не удалился поскольку ссылка на // него есть dimarik, это тот не приятный случай когда первый объект ссылается на второй, а второй на первый, при котором даже зануление не поможет. Последний раз редактировалось VitaliyKrivtsov; 28.01.2011 в 22:11. |
|
|||||
|
Очень интересная тема.
dimarik, я гружу все Bitmap`ы в текущий ApplicationDomain, т.к. коллапса идентификаторов по getDefinition никак не произойдёт. Но Цитата:
Это очень грустная новость. Что можешь посоветовать для загрузки "мимолетных" картинок, которые могут легко появится на экране и так же легко исчезнуть? Создавать каждый раз для картинки дочерний ApplicationDomain мне кажется совсем не хорошей идеей. Для групп картинок "на сеанс", вроде зашли в комнату - увидели лица людей, вышли, "убили" домен - как-то идея тоже чем-то не нравится.
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Пользуйтесь пожалуйста профайлером, все вопросы отпадут.
Наглядный тест: package { import flash.display.Bitmap; import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.net.URLRequest; import flash.utils.Dictionary; public class LoaderTest extends Sprite { protected var dict : Dictionary = new Dictionary(true); public function LoaderTest() { addEventListener(Event.ENTER_FRAME, enterFrameHandler); var loader : Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler); loader.load(new URLRequest("http://www.flasher.ru/forum/image.php?u=21620&dateline=1288193880")); dict[loader] = true; } private function enterFrameHandler(event : Event) : void { var b : Boolean = true; for (var prop : * in dict) { trace(prop); b = false; } if (b) { trace("deleted"); } } private function completeHandler(event : Event) : void { var loader : Loader = (event.target as LoaderInfo).loader; var bitmap : Bitmap = loader.content as Bitmap; var sprite : Sprite = new Sprite(); sprite.addChild(bitmap); sprite.addEventListener(MouseEvent.CLICK, clickHandler); addChild(sprite); loader.unloadAndStop(true); } private function clickHandler(event : MouseEvent) : void { var spr : Sprite = event.target as Sprite; spr.removeEventListener(MouseEvent.CLICK, clickHandler); while (spr.numChildren) { spr.removeChildAt(0); } removeChild(spr); } } } Смотреть тест надо в профайлере с веселой кнопочкой "run gc" Последний раз редактировалось mayakwd; 29.01.2011 в 00:06. |
|
|||||
|
Регистрация: Nov 2009
Сообщений: 300
|
mayakwd опередил )
Профайлер избавит тебя от неизвестности, так как в нем можно не ждать пока GC решит освободить память, а запустить его принудительно и посмотреть на результат. Профайлер есть во Flex и FlashDevelop, это из тех что я знаю. |
|
|||||
|
Спасибо всем, теперь я узнал что такое профайлер.
А на самом деле замечание такое сказал весьма авторитетный человек и я уверен что слова его ну пустые. Флеш плееров много, в одной из проблема может иметь место. Остается дождаться комментариев. Но за то что вы провели тесты и сказали что в какой-то фп всё ок — спасибо )
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
адекватно работает в любом плеере начиная с 9ой версии, не скажу с какой именно так как проблем в принципе в этом вопросе не возникало.
вообще никто не ставил под сомнения слова димарика, но тесты показывают иную версию происходящего. а ставить авторитет выше адекватных данных попахивает предрассудками. Последний раз редактировалось mayakwd; 29.01.2011 в 00:45. |
![]() |
![]() |
Часовой пояс GMT +4, время: 02:29. |
|
|
« Предыдущая тема | Следующая тема » |
|
|