I am going over my code 开发者_如何学编程and trying to get a handle on proper memory management. This code:
imageView = [[[UIImageView alloc] initWithImage:myImage] autorelease];
Causes my application to crash. I am using multiple view controllers within a nav bar controller. The app works fine: I can select a person from the first view controller (tableview) and it puts me to a list of that persons photos, I can then select a photo from that view controller (tableview) and move to a final view with a scrollview for viewing the photo. Once I hit back on the navbar the previous view loads (list of photos in a tableview) however the app crashes right before the row is deselected using this code:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if(RowSelected != nil)
{
[MainTableView deselectRowAtIndexPath:RowSelected animated:YES];
}
}
The selected row is stored when a the user clicks a row.
If I leave the code as:
imageView = [[UIImageView alloc] initWithImage:myImage];
The app runs fine. Am I doing something wrong? Do I not need to autorelease this?
Make sure you create that view in your view controller's -loadView
or -viewDidLoad
, not in its initializer. When the controller's view goes offscreen it usually gets released, which in turn releases its subviews; thus, you should not expect your reference to imageView
to remain valid. If you for some reason need the image view to stay in memory even when the view controller's offscreen, then it's okay not to call -autorelease
when you create it; just make sure to call [imageView release];
in your controller's -dealloc
.
When you mark imageView for autorelease, it will be released the next time thru the run loop. If you still are referencing or using imageView somewhere then you are using a pointer to heap space that has been released. The heap space will get overwritten (sooner or later) and you will be referencing garbage and crash.
I think the correct solution is that imageView should be a property that is retained, but I'm not sure what you are doing with imageView so I'm only guesstimating here. If you add imageView to your view Controllers view it will retain it in the subviews array. Bottom line, it has to be retained by whoever is using it.
You would make imageView a retained property in the .h file:
@property (nonatomic, retain) UIImageView* imageView;
Then use the setter, which will retain it:
UIImageView* tmpIV = [[UIImageView alloc] initWithImage:myImage];
self.imageView = tmpIV; // copy the pointer, setter will retain it
[tmpIV release]; // release the original alloc
Don't forget the @synthesize to create the setter/getter.
The ImageView is in my .h. I am using this line it in my -viewDidLoad, i do not need the view once it goes offscreen:
imageView = [[[UIImageView alloc] initWithImage:myImage] autorelease];
I think that what i am doing is assigning the allocated UIImageView to my imageView and if i auto release then the retaincount will be off because my -dealloc releases? (corret me if im wrong)
if i check my -dealloc:
- (void)dealloc {
NSLog(@"%i", [photo retainCount]);
[photo release];
NSLog(@"%i", [imageView retainCount]);
[imageView release];
[super dealloc];
}
The retaincount of the imageView is 1 in NSLog, im guessing that when it goes to do [super dealloc] that it tries to take 1 more retain count off of the imageView when it is 0 already because of the [imageView release] ?
if i have the line: imageView = [[UIImageView alloc] initWithImage:myImage];
then the retain count is 2 in NSLog, 1 going into the [supper dealloc]
if i use kk6yb's method, then the app works no problems, however i think i shouldn't have to do it this way because using his way if i check my retain count in dealloc it is also 2 in the NSLog...
I am confused, i read alot about memory management yesterday to get a better grip on things, since i am releasing the imageView in the -dealloc i believe i do not need to autorelease on that line?
Is there a way to check memory leaks in xCode?
Thanks!
精彩评论