I got a UIImageView that i set in the nib file. I download an image from internet and sets the image to the UIImageView. When i’m releasing it has retain count 2? If i’m using only 1 release it won’t show any memory leak but i can see in “Instrument Allocations” that it never gets released. When i release the UIImageView twice like below then it works good. But i should never release it twice?!?!
in Header:
IBOutlet UIImageView *background;
in the .m loading the image:
/* Load Image code */
id path = [NSString stringWithFormat:@"http://www.image.com/aImage.jpg"];
NSURL *url = [NSURL URLWithString:path];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData* urlData = [[NSData alloc] initWithContentsOfURL:url];
[background setImage:[UIImage imageWithData:urlData]];
[urlData release];
[pool release];
in dealloc function:
- (void)dealloc {
NSLog(@"Backgroud count: %i",[background retainCount]); // Prints 2
[background release];
[background release]; // Does not "leak" if i have 2x release
[super dealloc];
}
This is the only code that is useing the UIImageView Background.
EDIT:
something i forgot to mention is that i run this code inside a for loop like this. but this for loop will only execute once! But it shouldn’t matter?
for (id theKey in dictionary) {
/* Load Image code above is here */
}
I believe that I’ve figured out what the trouble is. Apple recommends that you retain the objects you connect to through
IBOutlets (your image view, in this case). You said that you haven’t done so, but you should be following Apple’s recommendation. The reason that you should is outlined in a iphonedevsdk.com forum post about this problem, which links to a Big Nerd Ranch blog post that lays it all out.On iOS, the nib loading mechanism uses the setter if your outlet has one, but it uses key-value coding if not; specifically, it uses
setValue:forKey:, which retains the value (this is documented, but somewhat unexpected). Your image view, being the subview of your view controller’s top view, is retained by that view. It’s also retained by this key-value setting procedure. So, unbeknownst to you, your objects have two references to the image view. Apple makes the retaining property suggestion so that it becomes knownst to you that the view is being retained.You still shouldn’t be worrying about the retain count as such, but you should do one of two things: make this
IBOutleta retained property and release it in bothviewDidUnloadanddealloc(just once each, though!), or follow BNR’s suggestion and make the property explicitly assigned:in which case you do not have to release it yourself. In both cases, make sure you
@synthesizethe property accessors.Previously:
Don’t look at retain count, and if there’s no leak being detected, then don’t worry about it. The UIKit framework is likely retaining the view for reasons that you aren’t privy to.
Additionally, if
backgroundisn’t a retained property:and you’re creating it in the xib, you shouldn’t be releasing it at all, because you don’t own it. That is, you aren’t responsible for its memory; the actions that give you that responsibility are: calling
retainon the object, or creating it using a method whose name begins withalloc,copy,mutableCopy, ornew.