Как определить массив C неопределенного размера в качестве переменной экземпляра в Objective-C - PullRequest
2 голосов
/ 22 августа 2011

В Objective-C, как я могу определить массив C 'неизвестного размера' в качестве переменной экземпляра, а затем заполнить массив?

(Фон) : У меня есть класс в Objective-C, который обрабатывает загрузку игровых данных. Данные хранятся в массиве структур C, содержащихся во внешнем файле данных. Я могу загрузить массив и получить к нему доступ, но мне нужно, чтобы он был доступен по всему классу. То, что я пытаюсь сделать, это объявить «пустой» массив в переменных моего экземпляра, а затем (при загрузке) указать этот пустой массив или заменить его на тот, который я загрузил.

Вот так я загружаю свои данные ...

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

Так что этот код прекрасно работает для воссоздания моего массива frame2d структур - мне просто нужно знать, как я могу использовать это как переменную экземпляра.

Любая помощь приветствуется, спасибо.

Ответы [ 3 ]

3 голосов
/ 22 августа 2011

Объявите его как frame2d *, затем выясните, насколько большим он должен быть во время выполнения, и инициализируйте его с помощью calloc (numberOfFrame2Ds, sizeof (frame2d));

Или используйте NSMutableArray и оберните структуры в NSValueобъекты, если изменение размера и безопасность во время выполнения более важны, чем эффективность.

1 голос
/ 22 августа 2011

Когда вы говорите, что вам нужно, чтобы загруженные данные были «доступны для всего класса», это звучит так, как будто у вас будет только один массив, который вы хотите использовать для всех ваших объектов этого класса.Если это так, забудьте переменную экземпляра.Вы можете выставить глобальный frame2d * и получить доступ к своим объектам:

// 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.*/

То, что вы пишете Obj-C, не означает, что вы должны выбросить все, что хорошо работает в C.каждый объект, хранящий указатель на один и тот же массив, будет пустой тратой памяти.

Если вы хотите более объектный способ получения информации, вы можете добавить метод класса для доступа к ней, будь то + (frame2d *)framesили + (frame2d *)frameAtIndex:(NSUInteger)u.

1 голос
/ 22 августа 2011

Используйте указатель на объект frame2d в качестве переменной экземпляра:

frame2D *animationData;

Вам потребуется выделить массив во время выполнения, используя malloc.

Если весь файл не что иное, как фреймы, просто прочитайте его в объект NSData:

// 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];
}
...