Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need help understanding a specific alloc/release idiom in iOS/Objective-C programming

I'm an experienced C/C++ programmer starting to learn Objective-C development. I'm currently looking through the UICatalog sample and came across another instance of an idiom I've seen several places and never understood.

Code:

ButtonsViewController *buttonsViewController = [[ButtonsViewController alloc] initWithNibName:@"ButtonsViewController" bundle:nil];
[self.menuList addObject:[NSDictionary dictionaryWithObjectsAndKeys:
                                       NSLocalizedString(@"ButtonsTitle", @""), kTitleKey,
                                       NSLocalizedString(@"ButtonsExplain", @""), kExplainKey, 
                                       buttonsViewController, kViewControllerKey, nil]];
[buttonsViewController release];

AFAIK, this allocates and initializes a ButtonsViewController, creates an NSDictionary for the ButtonsViewController and adds the dictionary to an NSMutableArray called menuList (which is a member variable of the MainViewController where the above code lives) and then releases the buttonsViewController that it just created. Later, the MainViewController uses the dictionary entry to switch views to the buttonsViewController when necessary.

My question is: why is the buttonsViewController still valid after this code? It was allocated and released with no 'retains' between. Does adding something to an NSDictionary or NSMutableArray have an implicit 'retain'? If so, was I supposed to be able to figure that out somehow, or is it just one of those things you have to read and remember?

like image 724
Will McLafferty Avatar asked Dec 17 '22 18:12

Will McLafferty


2 Answers

It is standard procedure in the Cocoa frameworks for collections to retain the objects they contain. So yes, the mutable array is retaining the view controller.

This is always the case, unless the documentation says otherwise.

like image 149
Dave DeLong Avatar answered Dec 28 '22 07:12

Dave DeLong


So, while it's true that the object is valid afterwards because the collection retains it, I'm not sure it's useful to think of it that way. If you intend to use the object in that method after adding it to the collection, you shouldn't release it until you're done with it.

The way to think about it is this:

1) I have a claim of ownership of this object I created

2) Now the collection and I both have ownership of this object

3) Now just the collection does, and I shouldn't use the object because I don't have ownership of it

and ignore the fact that you can technically get away with not paying attention to 3 in this case.

This allows you to keep using the NARC (new-alloc-retain-copy) rule for thinking about what retains objects.

like image 43
Catfish_Man Avatar answered Dec 28 '22 06:12

Catfish_Man