To alloc, or not to alloc


#1

I’ve made my way through almost the entire book at this point, and a very simple question remains unanswered: When do I use alloc?

Now, the answer may seem obvious to some, but I’m afraid I am still unsure. I know that whenever I want to send a message to an object, I must allocate memory and initialize that instance of that object. Fine, got it. So why don’t we just send [[someObject alloc] init]; to every object we send a message to?

It is my understanding that this is because some objects are sent an implicit autorelease message. For example: NSString *aString = [NSString stringWithFormat:@"format"];
This creates the pointer for our aString variable and autoreleases it.

Ok, well maybe we should only alloc init objects that we create (i.e. Possession, TouchDrawView, HTTPServer). Again, not the case: [[NSURLConnection alloc] initWithRequest:req delegate:self];

So, I am left wondering how to know whether to alloc init an object, to alloc initWithSomeOtherFormOfInit the object, or let Objective-C create an autoreleased instance of the object. Is there no hard and fast rule, or did I miss something around page 4 and just never pick up on it? Help is appreciated.


#2

You should definitely go through the Objective-C and Memory Management chapters (just to read them) again.

But yes, you have two ways of getting an object: alloc/init or using a convenience method. Convenience methods (which don’t contain the word alloc or init) return an autoreleased object.

There isn’t much of a difference between getting back an autoreleased object and retaining it immediately versus getting back an object from alloc/init. It’s generally considered better practice to alloc/init instead of the former, though.

If you want an object to keep, you alloc/init it. If you want a temporary object so you can use it quickly or give it out to another object, you use a convenience method if one exists. These methods are “convenient” because you don’t have to release the object afterwards.

I’m not sure what you are saying with the NSURLConnection example: you are definitely creating an instance of NSURLConnection.

As far as whether to use init or initWithBlahBlah, well, it’s up to the class you are instantiating. Each class has a designated initializer (like NSURLConnection’s initWithRequest:delegate: method) that you should use to initialize instances of. Using just init may not have the intended result.

Also, when it comes to convenience methods, the signature of the method is similar to the init method that gets called, for example:

+ (id)stringWithFormat:(NSString *)fmt, ...
{
      return [[[NSString alloc] initWithFormat:fmt, ...] autorelease];
}