Is there any documentation that discusses the leaky nature of convenience methods? I have seen other people comment that convenience methods should be avoided but have not seen anything that supports the assertion.
I use
[[UIImageView alloc] initWithImage[UIImage imageName:@"myPic.png]];
as well as the string methods frequently.
I apologize, I can't remember the exact reference, but I read something about memory and calls like that recently in apple's documentation. I htink it was in the "Programming for iPhone OS overview" document. The general idea is that [NSString stringWithFormat:] and similar functions should return an autoreleased string. Apple says that these calls should follow their standard get rules. You can read up on those here. They deal with core foundation, but I think the idea is the same with the iPhone SDK.
Okay, here's the long and short of it. Well, mostly the short of it. I don't remember exactly where in the documentation they mention it, probably the iPhone Programming Guide or whatever that intro-level guide is called. At WWDC, there were several presenters who really harped on the avoid-convenience-methods mantra, especially the guys from the power team.
Autoreleased objects aren't really a problem per se. We have to use them, they are a fundamental aspect of Objective-C's memory management model. It's not necessarily a problem to use them in most situations. The only impact is that the objects stick around a little while after you are done with them.
The problem is that the iPhone is more resource constrained than regular computers, so you have to be more careful with your heap allocations. The earliest that an autoreleased object will go away is the end of the current running event loop.
It is perfectly appropriate to use autorelease for its original purpose - to make sure an object sticks around long enough for a calling method to retain it. However, a lot of class convenience methods (like stringWithFormat: ), all they do is save you typing one or two lines of code, so you're adding objects to the autorelease pool and that will stick around after your method is all done to save typing a line of code... not a good idea.
If you're initializing stuff in viewDidLoad or awakeFromNib or application:didFinishLaunching, the use of a convenience method isn't going to be a problem at all. If it's a few strings here and there, no problem generally.
If you're creating an object that has to be passed back to a calling method, you might as well use the convenience methods because you're going to have to autorelease the object before you return it anyway to avoid having them deallocated before the calling method can retain it.
The thing you have to be careful about is large objects - NSData and large NSString objects, UIImages, etc. as well as anytime you autorelease inside of a loop. Remember, if you're in a loop, the event loop can't get to its end where it releases all the stuff with a zero retain count, so everything you autorelease in the loop will stick around throughout the loop, which is an easy way to trigger a low memory warning. One way to deal with that is to create a new autorelease pool for the loop, or even for each iteration through the loop if necessary, because when you drain or release the pool, it will get deallocate all the items with a zero-count. In those situations, if you can avoid using the autorelease pool by using alloc/init/release instead of a convenience method, then you really should - that extra one or two lines of code could buy you back a fair chunk of your heap.
Is this the type of information which will be included in your upcoming book?
We thought it would be more fun to leave people in the dark about this stuff and make them discover it the "hard way".
I'm kidding, of course. While we assume a working knowledge of Objective-C, we do include discussions of iPhone-specific considerations such as this, and we also cover the new Objective-C 2.0 features since most of the available objective-C books don't cover the 2.0 material.
We're trying very hard to incorporate "best practices" to the extent that they exist, unfortunately, we're hitting a moving target with this, several chapters have been rewritten multiple times already. I'm sure some patterns will emerge as the "best" way to do certain tasks after we go to press, but we're explaining what we do and why at each step and will keep the book and source code up to date using a website.
My big concern right now is the NDA - we haven't even been able to show the wokrk-in-progress manuscript to our publisher yet. I thought it would drop at WWDC, then with the release of 2.0, and both of those guesses turned out to be wrong. Frustrating.
As of right now, we've got almost 250 pages, we have a minimum of 350 in our contract, but I'm guessing we're going to be well over 400 to cover what's in our proposed TOC, and we may even have to cut one or two chapters or push them to a second more advanced book. Or manuscript deadline is the 31st of this month, but if the NDA doesn't drop soon, it will get pushed.
Thanks for asking and giving me the opportunity to throw in a shameless plug
Lots of places / books tell you "how" to do something.
I think it's important to know *why* as well. How's can and
will change, but the reason why tends to remain.
This is important with things like best practices -- exactly *why*
is this a best practice (who says it is, and *why*), etc.
Example (sad, trivial, I know... but real, nonetheless):
Why is this a *bad* thing to do, in terms of coding style:
if ( blah )
{
}
// Nice big comment here
// explaining WHAT we're doing
// in the else clause, instead of *why*
// ...
else
{
}
Scott
ps: many people know an MX record can't be a CNAME...
but why? sure, everyone SAYS so, but why? Which
RFC states this -- and what, exactly, does it state? uh huh.
Again -- WHY can an MX record not be a CNAME? :-)