PDA

View Full Version : Memory leaks




cjlesh
Jan 18, 2009, 08:32 PM
I'm still very new to memory management in general, having only programmed in languages where it wasn't really a consideration.

As I was working through an example in the Apress "Beginning Iphone Development" book, I ran into something I can't understand, and I'm hoping someone here can point me in the right direction.

In Chapter 6, page 126, there is the following code:


...
@synthesize blueViewController;
...
- (void)viewDidLoad {
BlueViewController *blueController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];
self.blueViewController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];
[self.view insertSubview:blueController.view atIndex:0];
[blueController release];
}
...

OK, I don't want to reproduce the entire project's code here, but in the header file there is:

@property (retain, nonatomic) BlueViewController *blueViewController;

and in the dealloc method:

[blueViewController release];

So, I was wondering why I can't do this instead:

- (void)viewDidLoad {
self.blueViewController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];
[self.view insertSubview:blueViewController.view atIndex:0];
}

I asked this question on the book's forum, and was told that my code will result in a memory leak, because alloc increased the ref count by 1, and assignment increases the ref count by 1, and I release blueViewController later, but that leaves a ref unreleased.

So, that makes sense to me, except when I run my code through 'Leaks', I'm not finding any.

Which leads me to my questions:
1. Why am I not seeing any leaks with my code?
2. Do I really have to create then release a temp variable every time I want to create an object that is assigned to an instance variable?
3. I tried reading the Apple docs on memory management, and they are over my head. Is there anywhere I can read about memory management in Objective C that won't make my head hurt?

Thanks in advance.



tsornin
Jan 21, 2009, 10:36 AM
So, I was wondering why I can't do this instead:

- (void)viewDidLoad {
self.blueViewController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];
[self.view insertSubview:blueViewController.view atIndex:0];
}


I do the above all the time without problems. You should add a [blueViewController release] to your dealloc method.

So, this code:

BlueViewController *viewController = [[blueViewController alloc] initWithNibName:@"BlueView" bundle:[NSBundle mainBundle]];
self.blueController = viewController;
[viewController release];
NSLog(@"retain count for blue controller: %d", (int)[blueController retainCount]);


is the same as this:

blueController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:[NSBundle mainBundle]];
NSLog(@"retain count for blue controller: %d", (int)[blueController retainCount]);


Both should give you a retain count of 1. Which is what you want.

jnic
Jan 21, 2009, 10:59 AM
3. I tried reading the Apple docs on memory management, and they are over my head. Is there anywhere I can read about memory management in Objective C that won't make my head hurt?

http://www.stepwise.com/Articles/Technical/HoldMe.html

newb16
Jan 21, 2009, 01:07 PM
- (void)viewDidLoad {
BlueViewController *blueController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];
self.blueViewController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];
[self.view insertSubview:blueController.view atIndex:0];
[blueController release];
}
...

The code in the book ( at least in the googlebooks ) is different in one line -
self.blueViewController = blueController

Else you end up with one controller and insert'ed Subview from different (another) controller.

cjlesh
Jan 21, 2009, 09:22 PM
newb16:

You are correct, the code I pasted above is not the code from the book, it is actually what you provided. I should have pasted:

...
@synthesize blueViewController;
...
- (void)viewDidLoad {
BlueViewController *blueController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];
self.blueViewController = blueControler;
[self.view insertSubview:blueController.view atIndex:0];
[blueController release];
}
...

In fact, I've done more reading on this, and seen similar code in Apple's examples, so maybe this is a common idiom? Create a temp variable, allocate a new object to it, hand off the object to your property, then delete the temp variable. I can do it, it just seems needlessly verbose.

So, my original question still stands, does the code change I proposed introduce a memory leak? On the book's forum, the respondent insists that it does, and I can't argue with the reasoning (I don't know enough), but I'm not seeing any leaks when I run my code through 'Leaks'.

Anyway, thanks for the replies, I clearly need to learn more about memory management in Objective-C and Cocoa.

-cjlesh

newb16
Jan 22, 2009, 02:11 PM
newb16:

You are correct, the code I pasted above is not the code from the book, it is actually what you provided. I should have pasted:

...
@synthesize blueViewController;
...
- (void)viewDidLoad {
BlueViewController *blueController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];
self.blueViewController = blueControler;
[self.view insertSubview:blueController.view atIndex:0];
[blueController release];
}
...


The difference here is that if you set result [[BlueViewController alloc] ...] to your property, then instead of "insertSubview:blueController.view" you need to write somthing like insertSubview:self.controller.view
where [self controller] ( as I understand properties) is one more selector call, instead of referencing local variable. It's no problem if you don't need it in this scope anymore.



So, my original question still stands, does the code change I proposed introduce a memory leak? On the book's forum, the respondent insists that it does, and I can't argue with the reasoning (I don't know enough), but I'm not seeing any leaks when I run my code through 'Leaks'.


To me - yes, as you first have retain count of 1 after alloc/init and then of 2 after retaining it in your property (retain, nonatomic), and after you release the property it is still 1.