Question

I have the following issue:

I have a primary view object (that inherits from UIView) that displays a grid of 16 squares (each is a class I created that inherits from UIImageView), in a 4x4 layout.

Each of these 16 squares is 160x160, and contains an image (a different image for each square) that is no bigger than 30kb. The image, however, is 500x500 (because it is used elsewhere in the program, in its full size), so it gets resized in the "square" class to 160x160, by the setFrame method.

By looking at the memory management feature of Xcode when the app is running, I've noticed a few things:

  1. each of these squares, when added to the primary view object, increase the memory usage of the app by 1MB. This doesn't happen at instantiation, but only when they are added by [self addSubview:square] at the primary view object.
  2. if I use the same image for all the squares, the memory increase is minimal. If I initialize the square objects without any images, then the increase is basically zero.
  3. the same app, when running in the simulator, uses 1/6 of the memory it does on an actual device.

The whole point here is: why is each of the squares using up 1MB of memory when loading a 30kb image? Is there a way to reduce this? I've tried creating the images in a number of different ways: [UIImage imageNamed:img], [UIImage imageWithContentsFromFile:path], [UIImage imageWithData:imgData scale:scale], as well as not resizing the frame.

Was it helpful?

Solution

When you use a 500x500 image in a smaller UIImageView, it's still loading the larger image into memory. You can solve this by resizing the UIImage, itself (not just adjusting the frame of the UIImageView), making a 160x160 image, and use that image in your view. See this answer for some code to resize the image, which can then be invoked as follows:

UIImage *smallImage = [image scaleImageToSizeAspectFill:CGSizeMake(160, 160)];

You might even want to save the resized image, so you're not constantly encumbering yourself with the computational overhead of creating the smaller images every time, e.g.:

NSData *data = UIImagePNGRepresentation(smallImage);
[data writeToFile:path atomically:YES];

You can then load that PNG file corresponding to your small image in future invocations of the view.


In answer to your question why it takes up so much memory, it's because while the image is probably stored as a compressed JPG or PNG in persistent storage, I suspect in memory it's held as an uncompressed bitmap. There are many internal formats, but a common one is a 32-bit format with 8 bits each for red, green, blue, and alpha. Regardless of the specifics, you can quickly see how a 500 x 500 pixel representation, with 4 bytes per pixel could translate to a 1 mb of memory. But a 160 x 160 image should be roughly one tenth the size.

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