views:

104

answers:

3

Hi, first question here, this is regarding the iPhoneOS3 not MacOSX. I am fairly new to Objective-C and I've never developed in a environment without automatic garbage collection so I am a little confused by this. Here's some valid code assigning a view controller to an app delegate from an example off Apple.com:

MyViewController *aViewController = [[MyViewController alloc]
    initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];
[self setMyViewController:aViewController];
[aViewController release];

So, from what I understand, I must release aViewController because it is first allocated (+1 = 1); then retained in the setter (+1 = 2); then released in the setter (-1 = 1); and then no longer needed so finally released again (-1 = 0) and the memory is freed. Wel could I not just skip assigning the temporary object aViewController and nest these functions like so:

[self setMyViewController:[[MyViewController alloc]
    initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]]];

I was wondering if this would work correctly? I am a little worried since the setter requires a pointer-to-ViewController instead of just a copy of one. And since I am only passing a return value, is the pointer-to-ViewController in the setter going to point to data that may be erased or lost before it can assign it? I am sorry if this seems like a dumb question, but I am having a hard time finding an answer anywhere, and I am trying to establish good techniques for non-garbage collection environments. Thanks!

A: 
[self setMyViewController:[[MyViewController alloc]
    initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]]];

here you allocate, then it is retained, so straight away you have a retain count of 2. but it would get set correctly, as you still pass the setter a pointer to the view controller.

If the property MyViewController was of type assign (not retain), you would only have a retain count of 1.

Aran Mulholland
Totally the wrong way to think about retain counts; never consider 'em as absolute counts. If you cause something to be retained, you should cause to it to be released (or autoreleased) when you no longer possess ownership. No more, no less.
bbum
(I didn't actually edit your comment -- just made enough of a whitespace change to remove my undeserved downvote.)
bbum
+1  A: 

Don't think of memory management in terms of absolute retain counts. Think of it entirely in terms of ownership and encapsulation.

When you alloc an object, you have created an object that you own. When you set that object as a value on another object, that other object should retain the object to express ownership. If your code is no longer interested in the object, you should then release (or autorelease it if you want to return it to something else).

[self setMyViewController:[[MyViewController alloc]
    initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]]];

To answer your specific question, the above line of code, by itself, will cause a memory leak assuming that -setMyViewController: is implemented correctly.

bbum
Peter Hosey has a great write up here on object ownership: http://boredzo.org/cocoa-touch-intro/
Rob Keniger
Well -setMyViewController is implemented using an retain then release, so they cancel each other out correct? And since I never allocate any memory for this data explicitly I thought it might not need release. So how would I go about fixing this?
Dooms101
Why would `-setViewController:` retain, then release, the view controller passed in? Post the code as that sounds distinctly like it falls into the "not implemented correctly" category. :)
bbum
+1  A: 

I've decided that this code works sufficiently and doesn't cause a memory leak:

MyViewController *aViewController = [[[MyViewController alloc]
    initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]] autorelease];
[setMyViewController:aViewController];

Thanks for all the help guys!

Dooms101