Reputation: 9021
In Objective-C, how can I define a C array of 'unknown size' as an instance variable, and later populate the array?
(Background) : I have a class in Objective-C which handles loading game data. The data is stored in an array of C structs, contained in an external datafile. I can load in the array and access it, but I need it to be accessible throughout the class. What I'm trying to do is declare an 'empty' array in my instance variables and then (when loaded) point this empty array or replace it with the one I've loaded in.
This is how I'm loading in my data...
FILE *fptr = NULL;
fptr = fopen([path cStringUsingEncoding:NSUTF8StringEncoding], "r");
// Create an empty array of structs for the input file with known size
frame2d newAnimationData[28];
// Read in array of structs
fread(&newAnimationData, sizeof(newAnimationData), 1, fptr);
fclose(fptr);
So this code works fine to recreate my array of frame2d structs - I just need to know how I can use this as an instance variable.
Any help is appreciated, thanks.
Upvotes: 2
Views: 733
Reputation: 36143
When you say you need the loaded data to "be accessible throughout the class," it sounds like you will only have a single array that you want all your objects of that class to use. If so, forget the instance variable. You can expose a global frame2d *
and have your objects access that:
// Class.h
extern frame2d *gClassFrames;
// Class.m
frame2d *gClassFrames;
/* Somewhere in the class, read in the data and point `gClassFrames` at it.
* If the array is actually of known size, just declare the entire array rather
* than a pointer and read the data into that static storage, in order to avoid
* dynamic memory allocation.*/
Just because you're writing Obj-C doesn't mean you have to throw out everything that works fine in C. Having each object store a pointer to the same array would be a waste of memory.
If you want a more objecty way of getting at the information, you can add a class method to access it, whether it's + (frame2d *)frames
or + (frame2d *)frameAtIndex:(NSUInteger)u
.
Upvotes: 1
Reputation: 9768
Use a pointer to a frame2d object as an instance variable:
frame2D *animationData;
You'll need to allocate the array at runtime using malloc.
If the entire file is nothing but frames, just read it into an NSData object:
// in the interface
@interface MyClass
{
NSData *animationData;
frame2D *animationFrames;
}
// in the implementation
animationData = [[NSData alloc] initWithContentsOfFile:path];
animationFrames = (frame2D*) [myData bytes];
-(void) dealloc {
[animationData release];
}
Upvotes: 1
Reputation: 41801
Declare it as frame2d*, then figure out how big it needs to be at runtime and initialize it with calloc(numberOfFrame2Ds, sizeof(frame2d));
Or use an NSMutableArray and wrap the structs in NSValue objects if resizing and safety at runtime is more important than efficiency.
Upvotes: 3