views:

142

answers:

6

In the following function which one is the best practice?

  1. To send an autoreleased object, and make the caller retain it?

  2. or send an allocated object, and make the caller release it?


- (NSString*) convertDataToString :(NSData*)myData
{
     //just an example, method might not exist
     NSString *str = [[NSString alloc] initWithData:myData];
     return str;
     return [str autoRelease];
}
+2  A: 

You'd want to return an autoreleased object most of the time. Unless your method name contains one of the following words [alloc, new, copy], you should return an autoreleased object.

Jacob Relkin
A: 

I prefer to return the autorelease. It means that you aren't hunting around trying to find where memory is being freed. Keeping memory allocation and deallocation together makes your life easier. After all, you're coding this, why make it harder on yourself.

No one in particular
+3  A: 

The memory management rules say your first example is — and this is a direct quote — wrong. It's not even a matter of preference, as some answers here seem to indicate. The caller does not normally own the object you return, so it should be autoreleased.

The specific example from the rules says this:

This is wrong. Following the ownership policy, it would result in a memory leak.

 – (NSArray *)sprockets {

    NSArray *array = [[NSArray alloc] initWithObjects:mainSprocket,
                               auxiliarySprocket, nil];
    return array;
}

The object’s reference to the new array object is limited to the sprockets method. After the method returns, the object loses its reference to the new object so cannot relinquish ownership. That in itself is not a problem. However, following the naming convention set out earlier, the caller is given no indication that it owns the returned object. The caller would therefore not relinquish ownership of the returned object, leading to a memory leak.

Chuck
A: 

Both are acceptable, but you should name your method accordingly : if the caller has the responsibility to deallocate it, you have to make this explicit by having your method name contain "create", "alloc" or "copy", else it should not. More reading on this at http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html%23//apple_ref/doc/uid/20000994-BAJHFBGH

It might be a bit more customary to return an autorelease object, but both are okay.

Jean
You should not add those words to arbitrary method names as an excuse to ignore the memory management rules. `alloc` and `copy` have specific meanings. If you're not doing the work of `alloc` or `copy`, you shouldn't use that in your selector.
Chuck
"Create" is not part of the Cocoa rules. That's part of the "Create rule" from Core Foundation. In Core Foundation, the words are "copy" and "create." In Cocoa they are "new," "alloc," and "copy." I generally avoid the word "create" in Cocoa methods to prevent confusion.
Rob Napier
+7  A: 

Following up on @Chuck's comment, -convertDataToString must not return an object that the caller must release. That would violate the Three Magic Words. If you do not have "copy," "alloc," or "new" in your name, the caller cannot be expected to release the object. If you have "copy" in your name or start with "new" or "alloc," then the caller must release the object.

Objective-C relies heavily on consistent naming and the names mean things. If you learn the naming, then you won't have any problems.

Rob Napier
great tip and clarification of the importance of convention in objective-c. in the managed c# world where I live convention exists, but is a nicety (apart from in asp.net mvc perhaps). it seems in objective-c, it's actually a cog in the machine.
andy
Hi Rob, Does it mean that if the function name is newStringFromData, we can expect the caller to release the object once he has used it.
Krishnan
@Krishnan, for that method, we expect the caller to deal with one extra retain. The caller may or may not be the one who releases the object (he might be called newStringFromSomethingElse:). But the point is, there should be one excess retain on the object when we return it.
Rob Napier
Thanks Rob.. That answered my question.
Krishnan
+1  A: 

If you create, alloc, or copy an object, you are responsible for releasing it. Based on this, you should return an autoreleased object.

JakeVA