views:

94

answers:

2

Can someone explain the difference between these two, the first one is taken from allowing xcode to automatically generate the declaration, the last one is taken from an example in "Cocoa Programming" by Aaron Hillegass.

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

.

- (NSString*)planetName {
    return planetName;
}

I am just curious whats going on, my understanding was that the method is returning a pointer to either nil or an existing string object. I don't understand the reason for retaining and then adding to the autorelease pool?

A: 

In both cases, yes, they are both returning a pointer to either nil or the string object.

The difference is that the first code block handles memory management, the second does not. The second code block is assuming you are managing planetName somewhere else in your class instance, whereas in the first code block Apple is being as conservative as possible in keeping that memory from leaking. By putting the memory in the current autorelease pool it will be destroyed with the pool.

My recommendation would be to stick with the latter case and to be a little wiser about managing your own object instances than what XCode is auto-generating for you.

fbrereto
Following the second pattern without understanding exactly why will lead to mysterious crashes for those new to Cocoa. Follow the first pattern [defensive] then optimize later is likely more productive.
bbum
A good point.
fbrereto
If I added a dealloc method to the class that did a [planetName release] would that constitute "wiser memory management" and allow me to safely use the shorter "return planetName;"? I already have that, I think I might be getting confused and *over* managing, I know equally bad.
fuzzygoat
The basic philosophy is "object ownership" -- you want to pick an object that "owns" `planetName` and track its retain/release calls within that object. I would recommend bbum's link on memory management- it may take a little while to get through, but it's a good resource and will take you a long way.
fbrereto
That would be why you need to read the memory management guide; whether you use retain/autorelease has absolutely nothing to do with dealloc.
bbum
I only mentioned dealloc because I thought that if I was not tagging planetName for release in the "getter" then I would need to properly dispose of it when I finally release its parent object.
fuzzygoat
+4  A: 

Consider:

NSString *planetName = [myPlanet planetName];
[myPlanet setPlanetName: @"Bob"];
[planetName length];

Without [[planetName retain] autorelease], the above will very likely crash.

retain/autorelease puts the object into the current thread's autorelease pool. That effectively guarantees that the object will remain valid until the pool is drained, which is typically after the current event -- user event, timer firing, etc... -- is done processing.

(1) Use @property and @synthesize. It generates correct getter/setters for you.

(2) Read the Cocoa Memory Management guide. It answers all of these questions quite well.

http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

bbum