2013-06-13 3 views
2

Как вернуть массив целых чисел C из метода Objective-C? Это то, что мой код выглядит так далеко:Как вернуть массив целых чисел C в Objective-C?

Вызов функции:

maze = [amaze getMaze]; 

Функция:

-(int*) getMaze{ 
    return maze; 
} 

Я только начал писать в Objective-C сегодня, так что это все ново для меня.

+0

Что не так с кодом, который вы указали? – borrrden

+0

Он не возвращает массив. – mlclmss

+0

Что такое 'лабиринт', и где вы его устанавливаете и доступ к нему? –

ответ

6

В C, если вам нужно вернуть массив из функции, вам необходимо выделить память для него с помощью malloc, а затем вернуть указатель, указывающий на вновь выделенную память.

После того, как вы закончите работу с этой памятью, вам понадобится free.

Что-то вроде:

#include <stdlib.h> /* need this include at top for malloc and free */ 

int* foo(int size) 
{ 
    int* out = malloc(sizeof(int) * size); /* need to get the size of the int type and multiply it 
              * by the number of integers we would like to return */ 

    return out; /* returning pointer to the function calling foo(). 
       * Don't forget to free the memory allocated with malloc */ 
} 

int main() 
{ 
    ... /* some code here */ 

    int* int_ptr = foo(25); /* int_ptr now points to the memory allocated in foo */ 

    ... /* some more code */ 

    free(int_ptr); /* we're done with this, let's free it */ 

    ... 

    return 0; 
} 

Это в стиле C, как он получает :) Есть, вероятно, другие (возможно, более подходящие) способы сделать это в Objective C. Однако, как Objective C считается строгим надмножество C, это также сработает.

Если я могу дополнительно расширить необходимость использования указателей. Массивы C-стиля, выделенные в функции, считаются local, после того как функция выходит за рамки, они автоматически очищаются.

Как указано другим плакатом, возврат из стандартного массива (например, int arr[10];) из функции является плохой идеей, так как к тому времени, когда массив возвращается, он больше не существует.

В C мы обходим эту проблему, динамически выделяя память, используя malloc и указав указатель на эту память.

Однако, если вы не освободить эту память адекватно, вы можете ввести утечку памяти или какое-либо другое неприятного поведение (например, free -ный на malloc -ED указателя дважды будет производить unwanted results).

+0

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

+0

Согласен. Я надеюсь, я дал понять, что это только C и что Objective C, вероятно, имеет лучшие способы сделать это :) – Nobilis

0
- (NSArray *)toArray:(int *)maze { 
    NSMutableArray *retVal = [[NSMutableArray alloc] init]; 
    for (int c = 0; maze[c] != NULL; c++) { 
     [retVal addObject:[NSNumber numberWithInt:maze[c]]]; 
    } 
    return [retVal array]; 
} 

Мне никогда не было удобно передавать изменчивые данные в и из методов и не знаю почему. Если вам нужно изменить значения позже, отправьте массив mutableCopy.

-1

вы можете сделать это таким образом

- (void)getArray:(int *)array withLength:(NSUInteger)length{ 
    for (int i = 0; i < length; i++) 
     array[i] = i; 
} 

int array[3]; 
[object getArray:array withLength:3]; 
NSLog(@"%d %d %d", array[0], array[1], array[2]); // 1 2 3 
+0

@downvoter, что случилось с моим ответом? –

+0

Я уверен, что ваш первый пример кода прослушивается. Вы не можете вернуть массив, потому что он распадается на указатель на стек стека, который вот-вот появится. – Chuck

+0

@ Чак Ты не ошибаешься. Я проверил код сборки и нашел, что он использует 'objc_msgSend_stret', что означает, что массив рассматривается как struct. Или, если вы считаете, что я ошибаюсь, и вы знаете правду, вы можете ответить на мой вопрос http://stackoverflow.com/questions/16709923/return-fixed-size-array –

4

Учитывая явно спросить о массивах C-стиле нет предложений здесь, что вы должны использовать NSArray и т.д.

Вы не может возвращающий C -style array (см. ниже) в качестве значения в Objective-C (или C или C++), вы можете получить ссылку на такой массив. может.

Типы, такие как int, double и struct x могут быть передаются по значению - то есть действительные биты, представляющие значение, передаются вокруг.Другие вещи; такие как массивы C-стиля, динамически распределенная память, объекты стиля Objective-C и т. д .; все передано по ссылке - это ссылка на местоположение в памяти, которое содержит фактические биты, представляющие значение, передаваемое вокруг.

Таким образом, чтобы возвращать массив С-стилем из функции/методы вы можете:

  1. динамически (mallocдр) массив и возвращает ссылку на выделенную память;
  2. Передача в ссылка на уже существующий массив и функция заполняет его; или
  3. Wrap массив вверх как struct ...

Нормальные варианты (1) или (2) - обратите внимание, вы не можете вернуть ссылку на стек выделяется массив, как:

int *thisIsInvalid() 
{ 
    int myValues[5]; 
    ... 
    return myValues; // will not work, the type is correct but once function 
        // returns myValues no longer exists. 
} 

Если вы действительно хотите вернуть (маленький) массив по значению, вы можете это сделать, используя (3). Помните, что значения struct передаются по значению. Таким образом, следующие будут работать:

typedef struct 
{ 
    int array[5]; 
} fiveInts; 

fiveInts thisIsValid() 
{ 
    fiveInts myValues; 
    ... 
    myValues.array[3] = ...; // etc. 
    ... 
    return myValues; 
} 

(Обратите внимание, что нет никаких накладных расходов из оберточной массива внутри struct, когда дело доходит до чтения/записи массива - стоимость в вышеуказанном копирует все значения обратно - значит, рекомендуется только для небольших массивов!)

HTH

Смежные вопросы