Jeremy L
Jeremy L

Reputation: 3810

Memory management of return value

I want to return multiple values from a method and I've decided to use an array to do so

-(NSArray *) foo {
    // some operations here
    return @[node, [NSNumber numberWithInt:i], [NSNumber numberWithBool:flag]];
}

an example is

-(NSArray *) foo {
    return @[@"hi", [NSNumber numberWithInt:3], [NSNumber numberWithBool:YES]];
}

Is this a preferred way, and since there is an NSArray object created like that, which needs to stay, but can be released when there are no new owners later, is it true that this needs to be in an autorelease pool?

-(NSArray *) foo {
    @autorelease {
        // some operations here
        return @[node, [NSNumber numberWithInt:i], [NSNumber numberWithBool:flag]];
    }
}

Upvotes: 0

Views: 165

Answers (4)

jscs
jscs

Reputation: 64002

You don't need to do anything when compiling with ARC -- it takes care of this memory management for you. In fact, putting the object into an autorelease block here is wrong, because you need the object to live past the end of the method and be returned to the caller.

Under MRR, you would make sure the return value was autoreleased, and that's what ARC is doing for you.

The autorelease pool that it's put in under either scheme, however, is at a higher level -- outside the called function.

Upvotes: 1

user529758
user529758

Reputation:

Nope. It's autorelease for the exact purpose in order not to have to release it explicitly. If you wrap the return XYZ.. statement in an autorelease pool, it'll either be released (which is not you want, since it's then deallocated and you return an invalid pointer to the caller function), or because of the function returning, the draining of the pool never occurs, and you essentially end up leaking the pool itself. You either don't add anything like this, or use the autorelease pool in the caller function.

Upvotes: 1

J2theC
J2theC

Reputation: 4452

That autoreleasepool is unnecessary. The runloop already has an autorelease pool, and the array you are creating on the return is tagged as autorelease, so, this array will be released.

You do not return multiple values from an objective-c method, just like you do not return multiple values from c. You can pass references to the method and assign the values within the method, or return collection objects containing the data you wish to return, or create a custom class that contains the response you wish to return from the method.

Upvotes: 2

DrummerB
DrummerB

Reputation: 40211

You have a few options.

  1. Create and return a dictionary. This has the advantage (over returning an NSArray), that you don't depend on the order or number of items on the array. You could return a few of the items conditionally.
  2. Implement a new class that represents the information you need to return. The class should have all the required properties, so you could just create an instance, set the properties and return it.
  3. Return by reference:

    - (void)someMethod:(int)argument returnValue1:(int *)ret1 returnValue2:(int *)ret2;
    

    You could then call it like this:

    int r1;
    int r2;
    [object someMethod:arg returnValue1:&r1 returnValue2:&r2];
    // r1 and r2 now contain the values that were set in the method implementation.
    

Upvotes: 1

Related Questions