views:

212

answers:

7

I am just curious, do I need to add a further [name release] elsewhere to match up with the retain here in the getter?

- (NSString *)name {
    return [[name retain] autorelease];
}

gary

+2  A: 

No, this is fine. autorelease will cause the value to be released when the current autorelease pool is drained.

Every retain must be matched with exactly 1 of either release or autorelease.

However, I believe both the retain and autorelease are unneeded here. Generally you want to use that autorelease idiom because you've alloc'ed something in the method.

nall
Thats what I was figuring, the retain just makes the NSString hang around.
fuzzygoat
But it's not this method's responsibility to make it hang around on behalf of the caller. The caller of this method should retain it if that's desired.
nall
+3  A: 

No, but you shouldn't need to do this at all since you are not allocating anything. You could simply return name and that should be fine. Was there a reason you needed to add this retain/autorelease?

A little more explanation, what is happening here is that your retain count goes up by one when you do a retain, and then down by 1 when the scope exists because of the autorelease.

slf
The code was simpy that generated by Xcode for the instance variable: NSString *name;
fuzzygoat
+1  A: 

No. The autorelease will balance it out. I don't think, however, that the retain and autorelease would be necessary. You can simply use return name.

Cory Kilger
The idea is that if something gets the property, then sets it, the object it got won't die on it. (I'd use `copy` instead of `retain`, especially if the object backing the property is mutable.)
Peter Hosey
+2  A: 

I don't know how your variable definition is in your class but the rule is that in your getter you should return the object unchanged for the reference count. It's the responsability of the caller to call retain if it want to keep a reference on it.

- (NSString*) name {
  return name;
}

// caller
NSString* name = object.name;
[name retain]; // if necessary. If the string is used only in the context of a method you do not have to retain it.

If you are using the returned value as a field in another class you should define your field like this:

@property(retain, nonatomic) NSString* name;

With this a retain will be called when you assign to the variable.

Vincent
don't forget the corresponding "@synthesize name;"
nall
A: 

I think I might have figured it out:

if [myString] is created outside the method then your safe to use ...

return myString;

if on the other hand [myString] is created inside the method and therefore needs to be released and returned, then you use.

myString = [[NSString alloc] initWithFormat: @"Send me home"]; 
return [myString autorelease];

This way the method sets [myString] to autorelease, Basically the object is created, set to autorelease and returned. The object will ultimately be released when the pool is destroyed.

fuzzygoat
The [ ] brackets in your first example are unnecessary. Returning `myObj` does *not* autorelease the object — it doesn't modify the retain count at all, which is the point. If you create an object inside a method, you shouldn't retain it before autoreleasing it. Generally, the object either has a +1 retain count (created via alloc/init, copy, etc.) and you autorelease, or a +0 retain count and you don't need to do anything. When you return an instance variable, the enclosing object is generally assumed to own the object, so you just return it without retaining/autoreleasing it.
Quinn Taylor
Based on your comments, why do Apple generate this return sequence from Xcode via "Place Accessor Def On Clipboard"?
fuzzygoat
Probably to handle cases when this is required. I wouldn't know without looking at it in detail, but in this case you can safely remove it.
Quinn Taylor
Sure, I have edited the answer to be a bit clearer, I am pretty sure you need an autorelease in there if say your using alloc to create an NSString to return.
fuzzygoat
fuzzygoat, that's correct. it's your lack of allocation that obviates the need for autorelease.
nall
Edited to add allocation, also variable changed from myObj to myString.
fuzzygoat
+1  A: 

As others have said, you do not need to retain or autorelease the property. Since callers of the 'getter' method did not create the object, they do not own it, and you are safe to assume that they won't tinker around with its retain count.

But, callers could potentially change the value of the variable returned by the getter, which would affect the object. Therefore, it would probably be a better idea to return a copy of your variable, especially since it is an NSString. (Getters for NSString objects often return a copy.)

- (NSString *)name {
    return [[name copy] autorelease];
}

In this scenario, you are creating a copy of the variable, so you 'own' it. By autoreleasing it before it is returned, you ensure that it will survive long enough to be used in the caller's scope, and that any changes they make to the 'name' variable will not affect the underlying object.

craig
True, thats a good point.
fuzzygoat
+1  A: 

I am just curious, do I need to add a further [name release] elsewhere to match up with the retain here in the getter?

- (NSString *)name {
    return [[name retain] autorelease];
}

No, because you are already releasing it. autorelease just means “send yourself release later”.

I think you should review the memory-management rules.

Peter Hosey
Reading them again, right now :) so can I take it that in this case the retain is paired with the autorelease?
fuzzygoat
The retain is balanced by the release that the autorelease causes. So yes, an `autorelease` message balances out a `retain` or `copy` message just as an immediate `release` message does.
Peter Hosey