BitmapData.rect creates a new rectangle?
I was working on some blitting code today and after profiling it found that I was creating 1000s of new rectangles. I was shocked because I only had 1 or 2 different new Rectangle() calls or I was using the .rect property of BitmapData.
I started commenting out huge swathes of code until I was left with this code in my sprite class: canvas.bitmapData.copyPixels(_bitmapData, _bitmapData.rect, destination, null, null, true);
I cached the result of _bitmapData.rect at object creation and my thousand of new rectangle calls were suddenly gone from the profiler.
Why the heck would BitmapData.rect create a new rectangle? Is there a way to check the core libraries or something and confirm this is true? It seems baffling.
Bethanny Anne said:
Why the heck would BitmapData.rect create a new rectangle? Is there a way to check the core libraries or something and confirm this is true? It seems baffling.
Imagine the following hypothetical situation where BitmapData.rect
always returns the same Rectangle instance:
public function BitmapDataRectTest()
{
var bmp:BitmapData = new BitmapData(100, 100, true, 0);
var rect1:Rectangle = bmp.rect;
rect1.width = 200;
var rect2:Rectangle = bmp.rect;
trace(rect2.width); // 200 <--- this would be wrong,
// the BitmapData is still only 100 pixels wide.
}
BitmapData.rect
returns a new instance every time to avoid that situation and to make sure you are getting the correct data in the returned Rectangle
instance.
Final note: this relates to 'pass-by-value' (primitive types) and 'pass-by-reference' (complex type) variables. For more info check out google or other posts on stackoverflow: Pass by reference or pass by value?
Interesting observation.
You can use the ===
operator to check if two instances of any Object
are the same.
It's likely that BitmapData
internally uses different data structures to maintain its visual state. The rect
property must be implemented as a getter function. However, one would expect that because the dimensions of BitmapData
are immutable, that the Rectangle
object would never need to be recreated, or even re-computed at all.
Edit: The rect
property on BitmapData
is read-only (no setter), however the properties on a Rectangle
are not. Creating a new instance of Rectangle
ensures that external objects cannot make mutations.
Yes, it sounds discouraging, but if you will take a look at BitmapData class source code you will discover this:
public class BitmapData extends Object implements IBitmapDrawable {
...
public function get rect() : Rectangle {
return new Rectangle(0, 0, this.width, this.height);
}
...
}
So the answer is Yes, AVM creates new instance of Rectangle in the heap every time you retrieve it through accessor-function.
链接地址: http://www.djcxy.com/p/20666.html上一篇: 为什么指定的对象有资格进行垃圾回收?