Инициализация массива структур в Objective-C - PullRequest
4 голосов
/ 18 марта 2012

Я читал об этом некоторое время, и я не уверен, что нашел хороший ответ.

Я пытаюсь настроить массив из 92 структур.Это фиксированная длина и не изменится, так как это эффективная таблица поиска.Я подумал, что лучший способ сделать это - сначала выделить память с calloc, а затем загрузить данные.

Но после некоторого чтения я вижу, что многие люди выделяют память напрямую без calloc или malloc, как это

 myStruct myData[92] = { {1,2}, {3,4}, ....};

Мой первый вопрос: лучше ли динамически распределятьпамять?Насколько я понимаю, это было лучшее решение.Особенно, если данные не обязательно будут использоваться постоянно.

Мой второй вопрос касается инициализации данных.Я читал, что могу инициализировать структуру, используя ... = {....};, но компилятор этого не принимает.

Вот код, который у меня есть:

typedef struct {
    int a;
    int b;
} myStruct;

@implementation MyClass

    static myStruct *myData;

    -(id) init {
         // ...

         myData = (myStruct *) calloc(92, sizeof(myStruct));
         myData[0] = {1,2}; // <=== Error ! Compiler says "Expected expression!"

         // ...

Ответы [ 3 ]

5 голосов
/ 18 марта 2012

Ваш код выглядит как Objective-C, это правильно?

Если вы знаете, сколько элементов в массиве (и это нормальный процессор и операционная система), всегда проще явно определить его.

Всякий раз, когда вы динамически выделяете массив, вам нужно защищаться от того, что что-то идет не так, что затрудняет понимание кода.

Если это действительно справочная таблица, и все значения известны во время компиляции, вы можете просто инициализировать ее:

struct {
    int a;
    int b;
} myStructDate[92] = { {1, 2}, {3, 4}, ... {181, 182}, {183, 184} };
3 голосов
/ 18 марта 2012

О вопросе 1: статически распределить массив должно быть просто отлично.Массив будет храниться в разделе данных вашего двоичного файла, загружаться в виртуальную память процесса и при необходимости заменяться операционной системой, как и любой другой фрагмент памяти, используемый вашим процессом.Это также сэкономит время при доступе к данным, поскольку вам не нужно выделять и инициализировать их.

О вопросе 2: gcc по крайней мере не нравится инициализация таких элементов массива.Но вы можете обмануть, используя временную переменную:

myStruct s = {1,2};
myData[0] = s;

Я не совсем уверен, что стандарт говорит об этом.

2 голосов
/ 18 марта 2012

Поскольку это не инициализация, вам нужно выполнить присваивание

myData[0].a = 1;
myData[0].b = 2;

Вы можете использовать инициализацию {} при инициализации, как в этом примере, который также устанавливает ваш массив. Это немного расточительно, так как вам не нужна переменная temp, если вы используете вышеуказанный метод.

myStruct temp = {1,2};
myStruct* myData = (myStruct *) calloc(92, sizeof(myStruct));
myData[0] = temp;

Хорошее эмпирическое правило о том, когда выделять память в куче (через malloc / calloc), если вам нужно использовать ее вне функции. В противном случае вам, вероятно, следует сделать это в стеке (с локальными переменными).

...