Вернуть несколько объектов из метода в Objective-C - PullRequest
5 голосов
/ 13 сентября 2010

У меня есть метод, который принимает NSMutableArray в качестве параметра, и я хотел бы, чтобы он возвращал этот массив, другой массив, созданный в методе, и int, созданный методом.Я понимаю, что это можно сделать, создав массив, содержащий все эти объекты, и вернув его, затем удалив их из массива вне метода, но есть ли другой способ вернуть несколько объектов?

Ответы [ 4 ]

9 голосов
/ 07 июня 2012

Типичные способы передачи нескольких значений:

  • Добавление дополнительных параметров по ссылке (например, NSErrors передаются таким образом)
  • Передача их в некоторых другихструктура или объект, обычно NSDictionary или пользовательский класс

. Выше приведены хорошие решения для многих ситуаций, но вот другое решение, которое может работать лучше всего в других ситуациях:

Добавитьblock to your method:

- (void)myMethodWithMultipleReturnObjectsForObject:(id)object returnBlock:(void (^)(id returnObject1, id returnObject2))returnBlock
{
    // do stuff

    returnBlock(returnObject1, returnObject2);
}

Затем используйте метод, подобный следующему:

[myMethodWithMultipleReturnObjectsForObject:object returnBlock:^(id returnObject1, id returnObject2) {
    // Use the return objects inside the block
}];

Объекты возврата в приведенном выше примере можно использовать только внутри блока, поэтому если вы хотите сохранитьих можно использовать за пределами блока, просто установите несколько переменных __block.

// Keep the objects around for use outside of the block
__block id object1;
__block id object2;
[myMethodWithMultipleReturnObjectsForObject:object returnBlock:^(id returnObject1, id returnObject2) {
    object1 = returnObject1;
    object2 = returnObject2;
}];
7 голосов
/ 13 сентября 2010

Использование NSDictionary для возврата нескольких значений является обычным способом сделать это в Obj-C.

Сигнатура метода будет выглядеть примерно так:

-(NSDictionary *)doSomeStuffThatReturnsMultipleObjects;

и вынам нужно определить ключи словаря в соответствующих файлах.

// Header File
extern NSString *const JKSourceArray;
extern NSString *const JKResultsArray;
extern NSString *const JKSomeNumber;

// Implementation File
NSString *const JKSourceArray = @"JKSourceArray";
NSString *const JKResultsArray = @"JKResultsArray";
NSString *const JKSomeNumber = @"JKSomeNumber";

Преимущество перед использованием массива состоит в том, что порядок элементов и наличие / отсутствие элементов не имеют значения, что делает егогораздо проще расширить в будущем, если вы хотите вернуть дополнительные объекты.Это также гораздо более гибкий и расширяемый способ передачи по ссылке.

2 голосов
/ 13 сентября 2010

Другой способ сделать это - передать указателю, который он хочет использовать, для хранения данных.Вот пример, который возвращает массив и использует указатели, чтобы дать вам значение типа int и другой массив.РЕДАКТИРОВАТЬ ОК, вот рабочая версия, которую я только что проверил сам:

- (NSMutableArray*)doStuff:(int*)container returnedArray:(NSMutableArray*)arrayContainer{
   int a = 4;
   *container = a;
   [arrayContainer removeAllObjects];
   [arrayContainer addObject:@"object"];
   return [NSMutableArray arrayWithObjects:@"object",nil];
}

Таким образом, вы можете сказать, как:

int value = 0;
NSMutableArray* new = [NSMutableArray array];
[self doStuff:&value returnedArray:new];

И это в основном работает как возврат!

0 голосов
/ 17 июля 2011

Возможно, вы захотите возвратить структуру.

typedef struct {
    NSMutableArray *array1;
    NSArray *array2;
    NSInteger integer;
} MyAwesomeReturnValue;

Ваш метод теперь может выглядеть так:

- (MyAwesomeReturnValue)myAwesomeMethod:(NSMutableArray *)parameter
{
    MyAwesomeReturnValue retval;
    retval.array1 = parameter;
    retval.array2 = [NSArray array];
    retval.integer = 5;

    return retval;
}

И вы бы использовали это как:

- (void)anotherAwesomeMethod
{
    NSMutableArray *array = [NSMutableArray array];
    MyAwesomeReturnValue returnedValue = [self myAwesomeMethod:array];

    NSLog(@"%@", returnedValue.array1);
    NSLog(@"%@", returnedValue.array2);
    NSLog(@"%d", returnedValue.integer);
}

Надеюсь, это помогло. ;)

...