I am newbie to iPhone programming. I am not using Interface Builder in my programming. I have some doubt about memory management, @property topics in iPhone.
Consider the following code
@interface LoadFlag : UIViewController {
UIImage *flag;
UIImageView *preview;
}
@property (nonatomic, retain) UIImageView *preview;
@property (nonatomic, retain) UIImage *flag;
...
@implementation LoadFlag
@synthesize preview;
@synthesize flag;
- (void)viewDidLoad
{
flag = [UIImage imageNamed:@"myImage.png"]];
NSLog(@"Preview: %d\n",[preview retainCount]); //Count: 0 but shouldn't it be 1 as I am retaining it in @property in interface file
preview=[[UIImageView alloc]init];
NSLog(@"Count: %d\n",[preview retainCount]); //Count: 1
preview.frame=CGRectMake(0.0f, 0.0f, 100.0f, 100.0f);
preview.image = flag;
[self.view addSubview:preview];
NSLog(@"Count: %d\n",[preview retainCount]); //Count: 2
[preview release];
NSLog(@"Count: %d\n",[preview retainCount]); //Count: 1
}
...
-
When & Why(what is the need) do I have to set @property with retain (in above case for
UIImage&UIImageView) ? I saw this statement in many sample programs but didn’t understood the need of it. -
When I declare
@property (nonatomic, retain) UIImageView *preview;statement the retain Count is 0. Why doesn’t it increase by 1 inspite of retaining it in @property. -
Also when I declare
[self.view addSubview:preview];then retain Count increments by 1 again. In this case does the “Autorelease pool” releases for us later or we have to take care of releasing it. I am not sure but I think that the Autorelease should handle it as we didn’t explicitly retained it so why should we worry of releasing it. -
Now, after the
[preview release];statement my count is 1. Now I don’t needUIImageViewanymore in my program so when and where should I release it so that the count becomes 0 and the memory gets deallocated. Again, I am not sure but I think that the Autorelease should handle it as we didn’t explicitly retained it so why should we worry of releasing it. What will happen if I release it in-(void) deallocmethod -
In the statement ->
flag = [UIImage imageNamed:@"myImage.png"]];I haven’t allocated any memory to flag but how can I still use it in my program. In this case if I do not allocate memory then who allocates & deallocates memory to it or is the “flag” just a reference pointing to ->[UIImage imageNamed:@"myImage.png"]];. If it is a reference only then do i need to release it.
Question 1
This means that the synthesized property accessor messages will include an automatic retain when the message is called (but ONLY when the message is called, see next).
Question 2
This is because you are not using the property accessor message, you are just assigning to the member variable. If you use:
The resulting retain count will be one (+1 for the init, -1 for the autorelease, +1 for the retain on the message).
N.B.
You will get the same retain count (one) if you do this:
(+1 for the init, not using the property accessor message so no extra retain). Up to you which way you go with.
Question 3
The addSubview will increment the retain count again because the preview will be stored in a collection which will retain it’s objects.
So yes, Basically if you are handing an object off to another object to manage (as is the case with addSubview) you can set it to autorelease and it will be released by the other object. However, since you are storing the UIImageVIew in a retained property, you will need to release it yourself (see next).
Question 4
Because you are keeping the preview object as retained property, you will need to release it in your dealloc message. So in my Question 2 example, you allocate the object, autorelease it, but assign it to retained property, so the retain count after all that will be one, you are adding it to a collection which will also retain it. When the view is cleaned up the collection will decrement the retain count, but you will need to call release as well, because you stored it in a retained property. So in your dealloc:
Question 5
imageNamed is a helper message that does the allocation, initialization and autorelease. So basically it is equivalent to saying.
You are storing it in a retained property (because I use self.flag in the above example), so you will need to release it in the dealloc message.