2009-06-18 14 views
18

können wir NSArray in c-Array konvertieren. . Wenn nicht, welche Alternativen es gibt [nehme ich brauche die c-Array in OpenGL-Funktionen zu speisen, wo die c-Array Vertex Zeiger von plist Dateien lesen Sie enthält]NSArray zu C-Array

Antwort

37

Die Antwort hängt von der Art des C-Arrays ab.

Wenn Sie eine Reihe von Grundwerten füllen müssen und bekannter Länge, könnten Sie so etwas tun:

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]); 

Hier ist ein Beispiel, wo wir eine neue C-Array von einem NSArray erstellen möchten, die Array-Elemente als Obj-C-Objekte halten:

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); 

Oder möchten Sie vielleicht nil -terminate das Array statt dessen Länge, das um:

// 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); 
+2

Dies ist eine großartige Antwort, ich wünschte, ich auf mehr stimmen könnte als einmal. Ich habe einen Vorschlag, der besagt, dass die Verwendung des 'NSString **' -Typs ein wenig verschleiert ist. Ich schlage vor, '[NSData initWithBytesNoCopy: length: freeWhenDone:] 'mit dem Zeiger, den malloc zurückgibt, und der Größe des Arrays zu verwenden. – alfwatt

+0

Ich versuchte den zweiten Ansatz, der Malloc verwendet, ich denke, es erfordert Arc deaktiviert werden. Zumindest, so habe ich es zum Laufen gebracht. Vielleicht existierte arc nicht, als diese Frage gestellt wurde .... –

4

würde ich selbst konvertieren vorschlagen, mit so etwas wie:

NSArray * myArray; 

... // code feeding myArray 

id table[ [myArray count] ]; 

int i = 0; 
for (id item in myArray) 
{ 
    table[i++] = item; 
} 
6

NSArray verfügt über eine -getObjects:range: Methode zum Erstellen eines C-Array für einen Teilbereich eines Arrays.

Beispiel:

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); 
+0

Das wird die NSNumber-Objekte jedoch nicht in einen primitiven numerischen Typ konvertieren. Der Fragesteller benötigt diese Konvertierung, um das C-Array mit OpenGL zu verwenden. Aus diesem Grund können sie das C-Array auch vollständig selbst bevölkern, ohne NSNumbers zu verwenden. –

+0

ahhh! Die OpenGL-Anforderung für das Problem wurde nicht angezeigt. In diesem Fall wäre ja eine manuelle Iteration des Arrays sinnvoll. –