Load UIImages correctly? Memory Management with "Leaks" - iphone

i´ve created a little game in which images are loaded when the user is touching the screen while moving. It depends on the screen position to load different images immediately.
I´ve got an UIImageView and because within the "touchesMoved" function, i´m loading the different images like this:
imageView.image = [UIImage imageNamed: [photos objectAtIndex: newImage ] ] ;
Now i want to improve my memory management using Instruments with "Allocations" & "Memory Monitor". Here´s i´m setting different snapshots with "Mark Heap" points and look for leaks. The line above is highlighted and now i want to know what´s wrong with it.. How can i improve that image-loading (without caching)?

Read this Dispelling the UIImage imageNamed: FUD
and also read the links in the question as well. Should answer everything you need.

First of all: imageNamed: does cache images.
If you're getting this line highlighted then there are 2 possible reasons (or both):
you're not properly releasing imageView
you're not properly releasing the photos array

+imageNamed returns an autoreleased object, yet the #property image in UIImageView retains it through its use until overwritten. -objectAtIndex: must return an object with a retain count of 1 which is not released.
If that indeed is the problem then the fix is
imageView.image = [UIImage imageNamed: [[photos objectAtIndex: newImage ] autorelease]];
However I doubt that is the real issue here.

Related

Releasing images not created with init

Hi every one I have the next issue I'm creating various images like this
UIImage *image = [UIImage imageNamed:_imageName];
and I'm assigning to one UIImageView
[self.imgvImage setImage:image];
The user when tap a button one UIImageView is created and one UIImage is assigning, I have 4 UIImageViews created when new is created the last is removed sending release to the UIImageView like this
[_imgvImage release];
But around than 100 times creating and releasing one memory warring happen but the app dont crash I think this is because the UIImages created are not releasing and there are so much because all the code are clean and creating and releasing are all fine.
How can I remove all the UIIMageView with his UIImage completely from the memory.
Please help, sorry for my English in not good.
The image created using below statement is handled by iOS. this image is stored in a cache so that next time you call this it is simply get returned from the cache.
UIImage *image = [UIImage imageNamed:_imageName];
I think you should not worry about memory warning as long as you are releasing what you are allocating (UIImageView in this case). iOS should clear this cache in case of memory crunch.
If you do not want that caching (e.g. when you are loading one image once only) you can use imageWithContentsOfFile: method of UIImage.
Hi I found the solution the solution was call the
NSAutoreleasePool
in the method when I removed the objects of the view like this:
for(ProductVW *pVW in [_vwProductsContainer subviews]){
NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePool alloc] init];
[pVW removeFromSuperview];
[autoreleasePool release];
}

IOS / iPhone loading images into UIImage based on slider value memory issue

I am loading images into a UIImage with the values of a slider (these are pages or slides, if you like). This UIImage switches them very fast with the use of a slider. Problem is, at some point, the app crashes on the device with an error of:
2011-04-02 17:39:01.836 Book1[2123:307] Received memory warning. Level=1
Here's the code:
- (IBAction)slidePages:(id)sender{
int sliderValue = pageSlider.value;
NSString *slideToPage = [NSString stringWithFormat:#"P%i.jpg", sliderValue];
imagePlaceholder.image = [UIImage imageNamed:slideToPage];
pageDisplay.text = [NSString stringWithFormat:#"Page %i", sliderValue];
currentPage = sliderValue;
}
Is there anything I could do to make it more efficient? Maybe the error is somewhere else but I'm guessing it has to do with the fast loading of images.
Still, I don't know how iOS deals with this. Every time I load a new image into the UIImage what happens with the "unloaded" one?
Thanks in advance.
One imortant aspect of [UIImage imageNamed] is that it caches all images loaded in that way and they never get unloaded, even if you dealloc the UIImage that was created! This is good in some circumstances (e.g. smallish images in UITableView cells), but bad in others (e.g. large images).
The solution is to use [UIImage imageWithData] which does not do this caching and which unloads the data when the UIImage is dealloc'd.
More info and discussion here:
Difference between [UIImage imageNamed...] and [UIImage imageWithData...]?
Update
This question has some good info on the question of [UIImage imageNamed:] not emptying its cache when a memory warning occurs.
[UIImage imageNamed:] caches images, so every image thus loaded effectively leaks. I don't know what the canonical solution is, but one option might be to load the image with CGImageCreateWithJPEGDataProvider() and initialise it with [UIImage imageWithCGImage:].
The original (wrong) answer:
You may need to release the previous image before loading the current one.
Loading a bunch of large images in iOS has always been a memory issue. As Marcelo mentioned, you should only keep around images are you currently viewing. All other images should be released so they can be garbage collected and the memory freed up. In my experience, even loading 2 fairly large images (500k-2mb each) will cause memory issues, especially on older devices with less RAM.

UIImage from NSDocumentDirectory leaking memory

I currently have this code:
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[imagesPath stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#.png", [postsArrayID objectAtIndex:indexPath.row]]]];
It's loading in an image to set in a UITableViewCell. This obviously leaks a lot of memory (I do release it, two lines down after setting the cells image to be that image), and I'm not sure if it caches the image at all.
Is there another way, that doesen't leak so much, I can use to load in images multiple times, like in a tableView, from the Documents-directory of my app? Thanks.
The leaks tool or Instruments should tell you what exactly is leaking. However, the image and imageView properties retain their images, so you may need to ensure you're properly releasing them in the dealloc method for the UITableViewCell. But like AngeDeLaMort said, we really need more information to give you a precise answer.
What is leaking exactly?
If you alloc an image and release it after, I don't see the leak your are talking about? Maybe more code or more precision would help.

UIButton setBackgroundImage consumes a lot of memory

I'm using the following code:
UIImage *buttonImage;
if (p.placeImage != nil) {
buttonImage = [UIImage imageWithData:p.placeImage];
} else {
buttonImage = [UIImage imageNamed:#"bg_place_noimg.png"];
}
[imageButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
When executing the app with Instruments I can see the setBackgroundImage consumes a lot of memory. However, if I comment the last line it doesn't happen. Any possible reason?
EDIT:
If p.placeImage == nil and imageNamed:#"bg_place_noimg.png" is used memory usage is normal. p.placeImage is a Transformable value I use in Core Data to store images NSData downloaded from Internet.
I'm not surprised that commenting out the last line causes less memory to be consumed. When you set that image as the background of your button, the image is most likely retained by the button and so the image remains in memory. If you don't apply the image as the button background, the UIImage's retain count is 0 and so its memory can be reclaimed by the system if necessary.
Kristopher's theory about the difference between imageWithData and imageNamed is also correct. Check out the Discussion section for each of those initializers in the documentation for UIImage.
I'm not sure, but I would guess that your problem is that imageWithData: creates a whole new image each time, whereas the imageNamed: method returns the same image over and over again.
You may need to add some code to cache and reuse images that are identical. For example, maybe you could use a URL as a key into a dictionary of images, and only create new images for URLs that have not been loaded before.

Converting an UIview unto UIimage causing memory leak

I'm developing an app for iPhone using a coverFlow view, when the app is building the cards it is using a UIView in order to add labels and other stuff. Then I convert the UIView into UIImage using the following code:
UIGraphicsBeginImageContext(imageView.bounds.size);
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// returning the UIImage
return viewImage;
Every Time I redraw the coverflow I have a huge memory allocation increment, that never decreases even if I dealloc my coverFlow view.
I think the memory leak is in the code that I added, what do you think?
There is no memory leak apparent in the code snippet you provided. That operation could not be performed on a background thread because of UIGraphicsBeginImageContext(), so you should have an NSAutoreleasePool in place (the return value of UIGraphicsGetImageFromCurrentContext() is autoreleased). Without further information, its impossible to tell where the memory leak could be - I suggest you look at whatever objects eventually own the viewImage object and make sure you are properly releasing the UIImage if you retain it.
Use drawViewHierarchyInRect:afterScreenUpdates: instead of renderInContext: it is 15x faster.
You can see the comparison on this article.
Also, I have created a Swift extension for doing this: https://stackoverflow.com/a/32042439/517707