Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

whitehexagon

macrumors regular
Original poster
May 12, 2007
147
0
I'm just starting to read how to manage my garbage. I've been using this example code to add a cancel button on a navigation bar. But I'm pretty sure UIBarButtonItem is going to need releasing at some point. Or is the autorelease here going to handle everything at the right time?

So my question is, what's the best way to clean this up? The view can be accessed many times, so I'm thinking static class variable and thus re-using the button, but then I won't really get a chance to release it. Alternative is to make it a class instance variable, but then I'm going to be constantly alloc/release these things.

Or is this code already the best/right option?

Code:
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]
    initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 
    target:self
    action:@selector(cancel)] autorelease];
 
There's no GC on the phone, although autorelease bears some similarity to the semantics of GC.

This is typically how this is done:

Code:
UIBarButtonItem*	cancel = [[UIBarButtonItem alloc]
    initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 
    target:self
    action:@selector(cancel)];
self.navigationItem.leftBarButtonItem = cancel;
[cancel release];

Your code using autorelease is correct also but slightly less efficient. There's no reason to make this an ivar.
 
Just curious,


Why is assigning and releasing 'cancel' only to use it to assign a navigation item better than simply directly assigning the navigation item as in whitehex's code?

Jerry
 
Just curious,


Why is assigning and releasing 'cancel' only to use it to assign a navigation item better than simply directly assigning the navigation item as in whitehex's code?

Jerry

You need to assign it to its own variable name so you can release it.

When it's created, it has a retain count of 1. Then you assign it to something and that increases to 2. Then you call release, and it goes down to 1 again. Now cancel is retained by the navigationItem, so when its done with it, its retain count will drop to 0 and it'll be destroyed.

The alternative is having an autorelease pool do it, but it doesn't necessarily release at the same time (I can't remember when autorelease releases, but I think it's different) and incurs an additional overhead.
 
Thank you very much.

Won't the navItem in the code
Code:
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
    initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 
    target:self
    action:@selector(cancel)] ;

also retain the, just created, cancel button with out the need to pack the cancel button into 'cancel' then release down one count allowing it to be destroyed when navItem further releases everything attached to it?

Shouldn't the, just created, cancel button also be retained by the navItem and released when it releases everything?

I really appreciate your explaining this. Thanks

Jerry
 
Thank you very much.

Won't the navItem in the code
Code:
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
    initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 
    target:self
    action:@selector(cancel)] ;

also retain the, just created, cancel button with out the need to pack the cancel button into 'cancel' then release down one count allowing it to be destroyed when navItem further releases everything attached to it?

Shouldn't the, just created, cancel button also be retained by the navItem and released when it releases everything?

I really appreciate your explaining this. Thanks

Jerry

Yes, but you don't have a handle to that cancel button, so you can't release it. The alloc makes its retain count 1, then the assignment increases it to 2. When the navItem releases it, it'll go back to 1.

Happy to help
 
The reason to use alloc/init/release rather than autorelease is that there is some overhead associated with the use of autorelease. It is considered a 'best practice' on the iPhone to avoid autorelease where possible.

Use of autorelease in this context is still correct. It won't cause any memory leaks or other problems. It just uses more resources than the explicit alloc/init/release code.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.