tags:

views:

1411

answers:

3
+1  Q: 

NSArray to C array

can we convert NSArray to c array. if not what alternatives are there.[suppose i need to feed the c array in opengl functions where the c array contains vertex pointer read from plist files]

+2  A: 

I would suggest to convert yourself, with something like:

NSArray * myArray;

... // code feeding myArray

id table[ [myArray count] ];

int i = 0;
for (id item in myArray)
{
    table[i++] = item;
}
mouviciel
+1  A: 

The answer depends on the nature of the C-array.

If you need to populate an array of primitive values and of known length, you could do something like this:

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

Here's an example where we want to create a new C-array from an NSArray, keeping the array items as Obj-C objects:

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

Or, you might want to nil-terminate the array instead of passing its length around:

// 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);
Will Harris
A: 

NSArray has a -getObjects:range: method for creating a C-array for a subrange of an array.

Example:

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);
Ashley Clark
That won't convert the NSNumber objects to a primitive numeric type, though. The questioner needs that conversion to use the C array with OpenGL; because of that, they might as well populate the C array entirely themselves, without ever putting NSNumbers into it.
Peter Hosey
ahhh! Didn't see the OpenGL requirement for the problem. In that case yes, iterating the array manually would be appropriate.
Ashley Clark