I often see something like the following:
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:@"Show" style:UIBarButtonItemStylePlain target:self action:@selector(refreshPropertyList:)];
self.navigationItem.rightBarButtonItem = anotherButton;
[anotherButton release];
specifically where a local var, in this case 'anotherButton' is used and then later released. Is this exactly the same as autoreleasing it when it is alloc'ed and then making sure it is used before the method ends? i.e.:
UIBarButtonItem *anotherButton = [[[UIBarButtonItem alloc] initWithTitle:@"Show" style:UIBarButtonItemStylePlain target:self action:@selector(refreshPropertyList:)] autorelease];
self.navigationItem.rightBarButtonItem = anotherButton;
I ask because I see it done the first way a huge amount of the time, but it feels less error prone (for me) to just autorelease it outright. Is it just a matter of personal style or are there differences to these two approaches apart from one methodically releasing the object after all is done with it, and the other taking care to claim it to be released at the outset so one doesn't accidentally forget to, both having merits.
Excellent question. By autoreleasing, you are delaying the automatic release of objects. This is all fine and dandy and expected behavior when you need to return something from a method, but keeping that object in memory longer than is necessary can be impactful to your app.
By releasing it when you are done, you are freeing the resource at that moment and the memory could be used by another object at runtime. In Cocos2D it is standard practice to autorelease nearly everything and things seem to work OK, but it still rubs me the wrong way and I would not do that in general practice.
From Allocate Memory Wisely in Tuning for Performance and Responsiveness Table 7-2 Tips for allocating memory:
When you autorelease something, you add it to a group of objects which will be released at some point in the future. This means that those objects still exist. Since iOS provides a limited amount of memory, it is suggested that you use release over autorelease whenever possible. You don't want your program to crash from low memory because you have a lot of autoreleased objects.
They accomplish the same thing. Some folks think you should avoid the use of autorelease whenever possible, so strongly prefer the release as soon as you can option. This was discussed here just yesterday.
In the code you cite, the difference between the two really is minimal. It's unlikely that
anotherButton
will be deallocated even after it's released because the assignment toself.navigationItem.rightBarButtonItem
probably causesanotherButton
to be retained.The best argument for calling release as soon as possible, IMO and in this situation, is that by releasing
anotherButton
you're explicitly documenting the fact that you're done using it. Also, the static analyzer will ding you if you useanotherButton
after the release. These two facts can help you avoid errors, and just make your code easier to understand.The argument in favor of autorelease in a situation like this is that it might be marginally easier to read. I think there's a reason that Apple gives us all those convenience methods like +stringWithFormat: -- they let you create and use the string you want with one method rather than three.