views:

45

answers:

3

I am a little confused about retain/release count when a local variable is allocated within a method, then returned to its caller. For example

-(NSMutableString*)foo { 
   NSMutableString *str = [[[NSMutableString alloc] init] autorelease];
   [str appendString:@"Just a test"];
   return str;
}

NSMutableString *myString = [self foo];

Questions: (as you can see I am quite confused by this case) 1. Will str retain count increment when it is assigned to myString? 2. Is it safe to autorelease in this case? 3. Who should clean up the memory?

Thanks.

+1  A: 

1) No

2) Yes - that's the correct pattern for this case. (You don't want callers to have to track and release this NSMutableString instance)

NSMutableString *str = [[NSMutableString alloc] init];
return str;

Would be bad because your caller is now forced to manage the returned variable.

Mr-sk
As to #2, that's why there are class methods to create autoreleased objects for you: `[NSMutableString string]`, and so on.
Carl Norum
+5  A: 

I would suggest you read the Cocoa memory management guidelines. All your questions are answered in there.

To answer about this particular code example: It's managing memory properly. This is what autorelease is for — where you need an object to stick around past a particular method invocation but still get released. You essentially turn ownership over to the autorelease pool.

And there's no magic to retaining and releasing. Assigning a local variable won't affect an object's retain count — it has to be sent retain or release for that to happen.

Chuck
Yeah I have read the documentation suggested 3 times and still didn't quite understand this scenario. Thanks all for the clarification.
twinkle
+2  A: 

There's no special magic involved.

  • When a retain message is sent to an object, its retain count increases.
  • When a release message is sent to an object, its retain count decreases.
  • When an autorelease message is sent to an object, it adds itself to a pool.
  • When the pool is drained (which may be at the end of a run loop or thread), anything in that pool gets sent a release message.
  • When an object receives as many release messages as it has retain messages (assuming there's an implicit retain caused by alloc), the object sends itself a dealloc message.

The retain count of an object is otherwise untouched (barring any optimisations).

dreamlax