如何在Objective-C中返回C样式的整数数组?

时间:2013-06-13 02:33:07

标签: objective-c c

如何从Objective-C方法返回C样式的整数数组?这是我的代码到目前为止的样子:

函数调用:

maze = [amaze getMaze];

功能:

-(int*) getMaze{
    return maze;
}

我今天刚刚开始在Objective-C上写作,所以这对我来说都是新的。

4 个答案:

答案 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)。

答案 1 :(得分:4)

鉴于你明确询问C风格的数组,这里没有建议你应该使用NSArray等。

不能直接返回一个C风格的数组(见下文)作为Objective-C(或C或C ++)中的值,你可以返回一个引用这样的阵列。

intdoublestruct x等类型都可以传递值 - 也就是表示值的实际位传递。其他事情;如C风格的数组,动态分配的内存,Objective-C风格的对象等;都是通过引用传递 - 这是对内存中某个位置的引用,该位置包含表示值传递的实际位。

因此,要从函数/方法返回C样式数组,您可以:

  1. 动态地(malloc )数组并返回对已分配内存的引用;
  2. 传递给对已存在数组的引用,并让该函数填满;或
  3. 将数组包裹为struct ...
  4. 正常选择是(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

答案 2 :(得分: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消息。

答案 3 :(得分:-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