views:

505

answers:

2

Malloc like this

int **terrain;
terrain = malloc(sizeof(int*) * mapSize.x);
for (int i = 0; i < mapSize.x; i++) {
    terrain[i] = malloc(mapSize.y * sizeof(int));
}

Use it. Convert to NSdata like this before saving

NSData *data=[NSData dataWithBytes:terrain length:(30*sizeof(int*) +30*30*sizeof(int) )];   
[rootObject setValue:data forKey:@"terrain"];
[NSKeyedArchiver archiveRootObject: rootObject toFile: path];

loading into NSdata then converting back to int**

rootObject = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; 
NSData *data = [rootObject valueForKey:@"terrain"];
terrain =(int**) [data bytes];

With this code, is it saving the *int addresses then when I load the data it does not point to the correct data any more? Or do I have a problem with the "endianness" as described in Documentation

If it is the address issue, should i put a for loop when saving to convert *int to NSData then save all those and recreate the **int with another for loop/malloc?

+1  A: 

I haven't tested this but I suspect that with the mallocs above there is no guarantee that you will have a continuous area of memory allocated.

what you could do is save the data separately for all mapSize.x array of bytes:

int **terrain;
terrain = malloc(sizeof(int*) * mapSize.x);
for (int i = 0; i < mapSize.x; i++) {
    terrain[i] = malloc(mapSize.y * sizeof(int));
}

...

for (int j = 0; j < mapSize.x; j++)
{
    NSData *data=[NSData dataWithBytes:terrain[j] length:(mapSize.y * sizeof(int))];   
    [rootObject setValue:data forKey:[NSString stringWithFormat:@"terrain%i", j]];
}

[rootObject setValue:mapSize.x forKey:@"terrain"];
[NSKeyedArchiver archiveRootObject:rootObject toFile:path];
szzsolt
+1 for the memory not being in a continuous block. Also, Keith is actually archiving the pointers along with the data. You shouldn't archiving pointers because they will all be wrong when they are unarchived (the pointers will be different every time).
Tom Dalling
A: 

I would convert the 2D array into NSArrays before archiving, because it will save you a lot of hassle.

NSMutableArray* terrainForArchiving = [NSMutableArray arrayWithCapacity:mapSize.x];
for(int col = 0; col < mapSize.x; ++col){
    NSMutableArray* terrainCol = [NSMutableArray arrayWithCapacity:mapSize.y];
    for(int row = 0; row < mapSize.y; ++row){
        [terrainCol addObject:[NSNumber numberWithInt:terrain[col][row]]];
    }
    [terrainForArchiving addObject:terrainCol];
}

[NSKeyedArchiver archiveRootObject:terrainForArchiving];
Tom Dalling