PDA

View Full Version : garbage advice for example code?




whitehexagon
Jun 18, 2009, 02:34 AM
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?

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



PhoneyDeveloper
Jun 18, 2009, 09:39 AM
There's no GC on the phone, although autorelease bears some similarity to the semantics of GC.

This is typically how this is done:

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.

jerrywickey
Jun 19, 2009, 06:25 AM
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

Saladinos
Jun 19, 2009, 06:31 AM
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.

jerrywickey
Jun 19, 2009, 06:38 AM
Thank you very much.

Won't the navItem in the 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

Saladinos
Jun 19, 2009, 07:42 AM
Thank you very much.

Won't the navItem in the 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

PhoneyDeveloper
Jun 19, 2009, 09:03 AM
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.

whitehexagon
Jun 21, 2009, 01:58 PM
thanks all for the discussion around this topic, it really helped!