3
votes

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];
}
6
I'm just starting on Objective C, great question! - andy
I'm not sure whether it was just for example purposes, but NSString does not have an initWithData: method, but an initWithData:encoding: method. - dreamlax
"//just an example, method might not exist" :) i have it in comment - aryaxt
Oh, haha, I thought that was for the convertDataToString: method. - dreamlax

6 Answers

7
votes

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.

3
votes

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.

2
votes

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.

1
votes

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

0
votes

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.

0
votes

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.