I want to call a method which returns two values

basically lets say my method is like the below (want to return 2 values)

NSString* myfunc
   NSString *myString = @"MYDATA";
   NSString *myString2 = @"MYDATA2";
   return myString;
   return myString2;        

So when i call it, i would use??

NSString* Value1 = [self myfunc:mystring];
NSString* Value2 = [self myfunc:mystring2];

I guess im doing something wrong with it, can anyone help me out? Thanks

+7  A: 

You can only return 1 value. That value can be a struct or an object or a simple type. If you return a struct or object it can contain multiple values.

The other way to return multiple values is with out parameters. Pass by reference or pointer in C.

Here is a code snippet showing how you could return a struct containing two NSStrings:

typedef struct {
    NSString* str1;
    NSString* str2;
} TwoStrings;

TwoStrings myfunc(void) {
    TwoStrings result;
    result.str1 = @"data";
    result.str2 = @"more";
    return result;

And call it like this:

TwoStrings twoStrs = myfunc();
NSLog(@"str1 = %@, str2 = %@", twoStrs.str1, twoStrs.str2);

You need to be careful with memory management when returning pointers even if they are wrapped inside a struct. In Objective-C the convention is that functions return autoreleased objects (unless the method name starts with create/new/alloc/copy).

Thanks,How would i do that? I can set mystring and mystring2 but outside the method, how could i access its pointers? My C is very rusty.
Thank You, This seems to be a lot more complicated and my knowledge is not that far to understand structs! Ill have to buy a book on basic programming then a book on OOB to get to grips with this all.
Then stick to functions that return one thing for now. Use two separate functions instead.
+2  A: 

As you can only return one value/object, maybe wrap them up in an array:

-(NSArray*) arrayFromMyFunc
   NSString *myString = @"MYDATA";
   NSString *myString2 = @"MYDATA2";
   return [NSArray arrayWithObjects:myString,myString2,nil];

You can then use it like this:

NSArray *arr = [self arrayFromMyFunc];

NSString *value1 = [arr objectAtIndex:0];
NSString *value2 = [arr objectAtIndex:1];

You could pass results back by reference, but this is easy to get wrong (syntactically, semantically, and from memory management point of view).

Edit One more thing: Make sure that you really need two return values. If they are quite independent, two separate function are often the better choice - better reusabilty and mentainable. Just in case you are making this as a matter of premature optimization. :-)

Thanks, This seems like the easiest way !

Wrap the two strings in an NSArray:

- (NSArray*)myFunc
   NSString *myString = @"MYDATA";
   NSString *myString2 = @"MYDATA2";
   return [NSArray arrayWithObjects:myString, myString2, nil];

NSArray *theArray = [self myFunc]
NSString *value1 = [theArray objectAtIndex:0];
NSString *value2 = [theArray] objectAtIndex:1];
Why call the function twice?
It's not a good idea to call the function twice.
Thanks! THe Array seems to be the easiest way to do this!
+2  A: 

You can only directly return one value from a function. But there is a way of doing it.

-(void) myfuncWithVal1:(NSString**)val1 andVal2:(NSString**)val2
  *val1 = @"MYDATA";
  *val2 = @"MYDATA2";

Then to call it outside the method you'd use:

NSString* a;
NSString* b;

[self myfuncWithVal1:&a andVal2:&b];
Stephen Darlington
No matter what method you finally use, make sure you understand the implications on memory management: Who owns this object, should you release it, or is it autoreleased?
From this, how could i set val1 and val2 to strings outside the method
Good point. I think that my convention the values would be autoreleased, much as normal return values would be.
Stephen Darlington
+1  A: 
void myfunc(NSString **string1, NSString **string2)
    *string1 = @"MYDATA";
    *string2 = @"MYDATA2";


NSString *value1, *value2;
myfunc(&value1, &value2);

Remember that you need to pass a pointer to a pointer when working with strings and other objects.

Thanks, Im not that advanced to go into pointers, and seems the ARRAY is easier. once i know more about programming, i think pointers will be a lot easier. The reason why i wont do this is, if i have a problem, im not sure how i can fix it as im new to pointers. but Thanks for the reply AJM!
+5  A: 

You have a few options:

  • NSArray: Just return an array. Pretty simple.
  • Pointers: Pass in two pointers, and write to them instead of returning anything. Make sure to check for NULL!
  • Structure: Create a struct that has two fields, one for each thing you want to return, and return one of that struct.
  • Object: Same a structure, but create a full NSObject subclass.
  • NSDictionary: Similar to NSArray, but removes the need to use magic ordering of the values.
Also, return an NSDictionary which saves having to remember the order of the returned objects.
Thanks, It seems NSArray seems the best way
Don't forget that you can mark an answer as accepted by clicking the ✔ next to the answer. :)

I see everyone has mentioned an NSArray but I'd go with an NSDictionary so the values don't have to be added in order or even at all. This means it is able to handle a situation where you only want to return the second string.

- (NSDictionary*)myFunction {

   NSString *myString1 = @"string1";
   NSString *myString2 = @"string2";

   return [NSDictionary dictionaryWithObjectsAndKeys: myString1, @"key1", myString2, @"key2", nil];

NSDictionary *myDictionary = [self myFunction]
NSString *string1 = [myDictionary objectForKey:@"key1"];
NSString *string2 = [myDictionary objectForKey:@"key2"];
James Raybould