мы можем преобразовать NSArray в массив c. если нет, то какие альтернативы существуют. [Предположим, мне нужно передать массив c в функции opengl, где массив c содержит указатель вершины, считанный из файлов plist]
NSArray в массив C
Ответы (3)
Ответ зависит от природы C-массива.
Если вам нужно заполнить массив примитивных значений и известной длины, вы можете сделать что-то вроде этого:
NSArray* nsArray = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],
[NSNumber numberWithInt:2],
nil];
int cArray[2];
// Fill C-array with ints
int count = [nsArray count];
for (int i = 0; i < count; ++i) {
cArray[i] = [[nsArray objectAtIndex:i] intValue];
}
// Do stuff with the C-array
NSLog(@"%d %d", cArray[0], cArray[1]);
Вот пример, когда мы хотим создать новый C-массив из NSArray, сохраняя элементы массива как объекты Obj-C:
NSArray* nsArray = [NSArray arrayWithObjects:@"First", @"Second", nil];
// Make a C-array
int count = [nsArray count];
NSString** cArray = malloc(sizeof(NSString*) * count);
for (int i = 0; i < count; ++i) {
cArray[i] = [nsArray objectAtIndex:i];
[cArray[i] retain]; // C-arrays don't automatically retain contents
}
// Do stuff with the C-array
for (int i = 0; i < count; ++i) {
NSLog(cArray[i]);
}
// Free the C-array's memory
for (int i = 0; i < count; ++i) {
[cArray[i] release];
}
free(cArray);
Или вы можете захотеть nil завершить массив вместо того, чтобы передавать его длину:
// Make a nil-terminated C-array
int count = [nsArray count];
NSString** cArray = malloc(sizeof(NSString*) * (count + 1));
for (int i = 0; i < count; ++i) {
cArray[i] = [nsArray objectAtIndex:i];
[cArray[i] retain]; // C-arrays don't automatically retain contents
}
cArray[count] = nil;
// Do stuff with the C-array
for (NSString** item = cArray; *item; ++item) {
NSLog(*item);
}
// Free the C-array's memory
for (NSString** item = cArray; *item; ++item) {
[*item release];
}
free(cArray);
person
Will Harris
schedule
18.06.2009
Это отличный ответ, я хотел бы проголосовать более одного раза. У меня есть одно предложение, которое заключается в том, что использование типа
NSString** немного запутано. Я предлагаю использовать [NSData initWithBytesNoCopy:length:freeWhenDone:] с указателем, который возвращает malloc, и размером массива.
- person alfwatt; 30.09.2011
Я попробовал второй подход, который использует malloc, я думаю, что он требует отключения дуги. По крайней мере, так я заставил его работать. Может быть, дуги не существовало, когда был задан этот вопрос....
- person simple_code; 23.01.2017
NSArray имеет метод -getObjects:range: для создания C-массива для поддиапазона массива.
Пример:
NSArray *someArray = /* .... */;
NSRange copyRange = NSMakeRange(0, [someArray count]);
id *cArray = malloc(sizeof(id *) * copyRange.length);
[someArray getObjects:cArray range:copyRange];
/* use cArray somewhere */
free(cArray);
person
Ashley Clark
schedule
18.06.2009
Однако это не приведет к преобразованию объектов NSNumber в примитивный числовой тип. Спрашивающему нужно это преобразование, чтобы использовать массив C с OpenGL; из-за этого они могли бы также полностью заполнить массив C самостоятельно, даже не помещая в него NSNumbers.
- person Peter Hosey; 18.06.2009
ааа! Не видел требования OpenGL для решения проблемы. В этом случае да, итерация массива вручную будет уместной.
- person Ashley Clark; 19.06.2009
Я бы предложил преобразовать себя, например:
NSArray * myArray;
... // code feeding myArray
id table[ [myArray count] ];
int i = 0;
for (id item in myArray)
{
table[i++] = item;
}
person
mouviciel
schedule
18.06.2009