views:

1588

answers:

3

Suppose I have a function like this:

- (NSSet *) someFunction {
    //code...
    return [[[NSSet alloc] initWithObjets:obj1, obj2, nil] autorelease];
}

When I call this function, do I need to do retain/release the return value? I'm assuming I do.

However, what if I don't do autorelease, so someFunction now looks like this:

- (NSSet *) someFunction {
    //code...
    return [[NSSet alloc] initWithObjets:obj1, obj2, nil];
}

In this case, I'm assuming I need to release but not retain the return value.

My question is, what is the suggested/best practice for these kinds of situations? Is one or the other version of someFunction recommended? Thanks.

A: 

Hmm...

Normally, I follow this "way".

+ (id)MyObj {
  return [[[MyObj alloc] init] autorelease];
}

Releasing the object prior to returning it, the object will be deallocated before it reaches the calling object. This will produce an error. Avoid this error by using a autorelease pool instead. Originally introduced to me by Scott Stevenson of Theocacao. It's his and many, preferred way for Obj-C 1.0.

Rev316
+4  A: 

You should spend some time reading the Memory Management Programming Guide for Cocoa.

The short is that if you get your reference through a method starts with 'alloc' or 'new' or contains 'copy', you own the reference and do not have to retain it. You do have provide for its release, either through a direct release or through using autorelease.

If you get a reference any other way (through a class method or what-have-you), you do not own a reference, so you don't have to release. If you want to keep a reference, you have to retain it.

Over-all, it is really quite simple and effective.

Travis Jensen
it's alloc, not init that means that you own the reference I believe
cobbal
Yes, you are correct. Editing the original response to reflect that (for posterity's sake).
Travis Jensen
+1  A: 

The only reason you should do the code in the second example is if your method name begins with new, alloc, create, copy, or something like that.

Otherwise you are responsible for releasing (or autoreleasing) any object you allocate. The first example is the correct way to do most things.

The calling function should retain the value if it wants it to persist past the functions scope, but it is then responsible for releasing it at some later point.

cobbal