5

I'm working on serializing a class that supports NSCoding. I've setup encodeWithCoder and initWithCoder, and all the standard Objective C data types work fine.

What I'm struggling with is how to encode a few simple C arrays. For example:

int bonusGrid[5];
int scoreGrid[10][10];
int solutionGrid[10][10];
int tileGrid[10][10];

Short of breaking them up and encoding each int one-by-one, I'm not sure how to deal with them. Is there a "standard" way to handle C arrays?

Thanks!

2
  • 1
    Will you be using the data on other computers? Will there be endian issues? Commented Feb 12, 2011 at 3:03
  • iPhone and iPad only. Maybe Mac someday, but that's not a certainty. Commented Feb 12, 2011 at 4:29

2 Answers 2

7

One way would be to use NSData to wrap the arrays.

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:[NSData dataWithBytes:(void*)bonusGrid length:5*sizeof(int)] forKey:@"bonusGrid"];
    [coder encodeObject:[NSData dataWithBytes:(void*)scoreGrid length:10*10*sizeof(int)] forKey:@"scoreGrid"];
    ...
}

- (id)initWithCoder:(NSCoder *)coder
    if((self = [super initWithCoder:coder])) {
        NSData *data = [coder objectForKey:@"bonusGrid"];
        int *temporary = (int*)[data bytes];
        for(unsigned char i = 0; i < 5; ++i) bonusGrid[i] = temporary[i];
        data = [coder objectForKey:@"scoreGrid"];
        temporary = (int*)[data bytes];
        for(unsigned char i = 0; i < 10; ++i)
            for(unsigned char j = 0; j < 10; ++j)
                scoreGrid[i][j] = temporary[i*10 + j];
        ...
    }
    return self;
}

You could also use memcpy() to move the data back into your arrays, but it is not proper and not guaranteed to work on all systems (it does work on the iPhone and mac).

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the reply. I'm curious why you're using the temporary array when retrieving the bonusGrid instead of just using bonusGrid itself?
bonusGrid is an array, but the bytes method returns a pointer (which will be freed when the NSData object is released). Trying to assign a pointer to an array is illegal and will cause either a warning or error (I don't remember which, but I think it is an error). You need to copy the contents of the pointer to the location of the array.
Gotcha. Yours is the approach I'll probably take. Seems a shame there's no easier way to go about this. Apple provides a way to handle native C types, but not arrays of those types? That's an oversight in my book.
0

See the answer to this question. It details what you would need to do to convert the C array to an NSArray object.

1 Comment

I thought about this approach. It seems like it might be time intensive though. We're not talking about a ton of data, but looping through each value, creating an NSNumber, adding it to a NSMutableArray -- it seems like a lot of work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.