Iphone – release/autorelease confusion in cocoa for iphone

cocoaiphone

I'm slowly teaching myself cocoa for the iPhone(through the Stanford Class on iTunes U) and I've just gone through the part on memory management, and I wanted to hopefully get some confirmation that the assumptions I'm making on how memory is handled and how [release] and [autorelease] work. Since memory management is a really basic and fundamental, but very essential part of the programming experience, I'd like to make sure I'm doing it right.

I understand that anything with an alloc, new, or copy needs to be released.
If I do this:

NSString *temp = [[NSString alloc] initWithString:@"Hello World"];

Then I need to add [temp release/autorelease] eventually, since I have an alloc.

However, if I do this:

NSString *temp = @"Hello World";

Then it doesn't seem to need a release statement. Does the NSString class call autorelease automatically as part of the assignment?

Also, is there any difference between the two *temp objects here after these statements? They both contain the same string, but are there memory/usage ways where they differ?

Secondly, with properties, I'm assuming that the autorelease is handled automatically. If I have this:

@interface Person : NSObject
{
    //ivars
    NSString *firstName;
    NSString *lastName;
}

//properties
@property NSString *firstName;
@property NSString *lastName;

///next file

@implementation Person

@synthesize firstName;
@synthesize lastName;

- (void) dealloc
{

    //HERE!!!!

    [super dealloc];
}

I'm assuming I don't need to add [firstName release] and [lastName release] (at //HERE!!!!), since that's automatically handled by the properties. Is that correct?

I do understand that if I do this in code(assuming I've defined initWithFirstName):

Person *Me = [[Person alloc] initWithFirstName: @"Drew", lastName:"McGhie"];

that later I'm going to have to use [Me release/autorelease];

Any help confirming or correcting my understanding so far is greatly appreciated.

POST ANSWER WRITE-UP

I thought I'd write this all up after going over all the answers and testing out the suggestions and talk about what worked.

I do need to add the [firstName release], [lastName release], but I also need to add (retain) to the property descriptions. Not adding the (retain) caused warnings because it assumes (assign). Here's how I finally set up the class

@interface Person : NSObject
    {
        //ivars
        NSString *firstName;
        NSString *lastName;
    }

    //properties
    @property (retain) NSString *firstName;
    @property (retain) NSString *lastName;

    ///next file

    @implementation Person

    @synthesize firstName;
    @synthesize lastName;

    - (void) dealloc
    {
        [firstName release];
        [lastName release];
        [super dealloc];
    }

Best Answer

The rule is simple: if you alloc, copy or retain, it's your responsibility to release. If you didn't, it's not. However, if you need to rely on an object staying around, you have to retain (and subsequently release).

We can treat the string literal according to the rules - you don't need to release it because you don't own it. That's simple; there's no need to worry about whether they're special cases or not, just follow the rules and you'll be fine.

I wrote up a blog post with a collection of articles about the Cocoa memory management rules; I'd recommend following up some of the references.

Related Topic