Question

I have this code in my app:

var newImage = // ...

if (imageView.Image != null && imageView.Image != newImage)
    imageView.Image.Dispose ();

imageView.Image = newImage;

I have three related questions:

  • Does it immediately release the memory occupied by the previous imageView.Image?
  • If it does, is there a cleaner solution?
  • Does this have anything to do with NSAutoreleasePool?
Was it helpful?

Solution

Does it immediately release the memory occupied by the previous imageView.Image?

Not immediately but it should be much faster than waiting for the Garbage Collector.

Calling Dispose will drop the managed reference to the native UIImage. If nothing else (natively) has a reference to the UIImage (RetainCount == 0) then it will be freed (ObjC reference counting).

In your code imageView still has a reference to it until its Image property is set to newImage - which is why I answered not immediately.

If it does, is there a cleaner solution?

Not really. Letting the GC do it's work is cleaner looking - but image can be very big and are worth freeing asap.

Also it's not really worth (and would not be cleaner anyway) adding a local variable to make sure (if no other native reference exists) the image will be freed immediately - it will happen on the next line.

Does this have anything to do with NSAutoreleasePool?

Anything ? well it's memory related in both cases.

Creating images will use (cache) the current NSAutoreleasePool and will, eventually, be drained. If you process a lot of stuff (e.g. a loop) then it's often worth having your own, short-lived, pool to ensure a faster drain.

Some API (well know to require a lot of memory) are decorated with an attribute that will automatically add (btouch) an NSAutoreleasePool - but it's not easy to find out which.

In doubt you better use Apple Instruments to measure...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top