Почему повторные вызовы someContainer.addChild(myBitmap) дублируют мое растровое изображение?
Это такой нубский вопрос, я смущен, чтобы опубликовать его, но здесь идет.
В моем классе загрузчика изображений я загружаю Bitmap, а затем клонирую его BitmapData в другой Bitmap с помощью BitmapData.draw(). Затем класс хранит ссылку на клонированное растровое изображение, и первоначально загруженное растровое изображение получает, по-видимому, сборщик мусора, поскольку это была переменная, локально изменяемая для метода создания.
Затем клиентский класс получает растровое изображение из класса загрузчика изображений и использует container.addChild(), чтобы добавить его на сцену.
Затем пользователь может сделать это снова, загрузив новое изображение (с диска) и отобразив его на сцене. Предполагается заменить старую растровую карту.
Я думал, что растровые изображения похожи на все другие объекты DisplayObject в том смысле, что если вы добавляете addChild (), он отсоединяет его от того места, где он был в каком бы то ни было DisplayList, и перемещает его в новый контейнер. В случае использования addChild () для одного и того же объекта в одном и том же контейнере, я предположил, что на самом деле это ничего не даст.
На самом деле, теперь, когда я упомянул об этом, я не уверен, зачем его вообще нужно добавлять - так, как я считаю, код работает, я просто заменяю растровое изображение и поэтому он должен автоматически обновить тот, который уже есть на этап... так что я как-то должен создавать новые объекты, но я не уверен, как это происходит.
Вот код
// "Client" class. User clicks button, loads an image.
private var _customImage:Bitmap;
private function onImageButtonClicked():void {
_cameraRoll.showImagePicker(addImageButton, onImagePickerComplete); // last arg is callback
}
private function onImagePickerComplete():void {
var customImage:Bitmap = _cameraRoll.currentImage;
_customImage = customImage;
showCustomImage();
}
private function showCustomImage():void {
imageContainer.addChild(_customImage);
// Proof that multiple bitmaps get added!!!
for (var i = 0; i < imageContainer.numChildren; ++i) {
trace(imageContainer.getChildAt(i));
}
}
// Image Loader class
private var _currentImage:Bitmap;
private function onImageLoaded(event:Event):void {
var tempBitmap:Bitmap = event.currentTarget.content as Bitmap;
var tempBMD:BitmapData;
var rotationMatrix:Matrix = new Matrix();
tempBMD.draw(tempBitmap, rotationMatrix);
_currentImage = new Bitmap(tempBMD);
onImagePickerComplete();
}
// Do the callback on the client class
private function onImagePickerComplete():void {
if (_imagePickerCompleteCallback is Function) {
_imagePickerCompleteCallback.call(this, true);
}
}
Дополнительные следы подтверждают, что мы имеем дело с отдельными экземплярами, и что _customImage фактически никогда не имеет родителя! Это почти как если бы, добавляя его в DisplayList, он разделяет его.
Это странно, или это только у меня так? Растровое изображение всегда хранится в _customImage
на клиентском классе. А также _customImage
это единственное, что добавляется в клип контейнера. Так что, если он будет добавлен снова, не будет ли он просто двигаться? И почему назначение растрового изображения из класса загрузчика изображений не обновляет автоматически _customImage, который уже добавлен на сцене?
1 ответ
Класс Loader создает совершенно новый Bitmap с нуля, который является совершенно новым DisplayObject (без родительского элемента). Это передается _customImage
на клиентском классе, забивая предыдущий DisplayObject.
_customImage
просто имеет ссылку на DisplayObject, который уже был связан с контейнером, он не является самим DisplayObject, поэтому, когда его заменяют, он не заменяет экземпляр этого DisplayObject на сцене - он просто разрывает соединение с ним.
Ссылка на этот предыдущий Bitmap, который находится в DisplayList, остается в памяти, связанной с родительским контейнером. Мы можем вернуть его с getChildAt()
,
Вам нужно removeChild(_customImage)
до того, как забить ссылку.