Использование #define в операторе if - PullRequest
4 голосов
/ 29 декабря 2011

Можно ли использовать #define в операторе "если"? Следующий код работает, но я получаю предупреждение о том, что макрос переопределяется.

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
 #define TableViewHeight 916
 #define DisplayHeight 1024
 #define DisplayWidth 768
}
else {
 #define TableViewHeight 374
 #define DisplayHeight 480
 #define DisplayWidth 320
}

Я тоже пробовал это, но это не сработало:

#ifdef UIUserInterfaceIdiomPad
 #define TableViewHeight 916
 #define DisplayHeight 1024
 #define DisplayWidth 768
#else
 #define TableViewHeight 374
 #define DisplayHeight 480
 #define DisplayWidth 320
#endif

Есть идеи?

Ответы [ 6 ]

7 голосов
/ 29 декабря 2011

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

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

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
}
else {
}

Другими словами, после предварительной обработки у вас просто есть пустые if и else тела.

Если вы хотите изменить значение чего-либо на основе условия во время выполнения, тогда это должно быть подлинный объект, а не просто макрос препроцессора. Э.Г.

extern int TableViewHeight; // defined somewhere else
extern int DisplayHeight; // defined somewhere else
extern int DisplayWidth; // defined somewhere else

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
  TableViewHeight = 916;
  DisplayHeight = 1024;
  DisplayWidth = 768;
}
else {
  TableViewHeight = 374;
  DisplayHeight = 480;
  DisplayWidth = 320;
}
1 голос
/ 29 декабря 2011

#defines заменяются препроцессором до запуска компилятора.Это означает, что вы не можете установить их значение во время выполнения.Я могу сделать то, что вам нужно, примерно так:

В вашем файле .h:

static CGFloat TableViewHeight;
static CGFloat DisplayHeight;
static CGFloat DisplayWidth;

в файле .m (реализация класса):

+ (void)initialize
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
     TableViewHeight = 916.0;
     DisplayHeight = 1024.0;
     DisplayWidth = 768.0;
    } else {
     TableViewHeight = 374.0;
     DisplayHeight = 480.0;
     DisplayWidth = 320.0;
    }
}

В качестве альтернативы, вы можете сделать что-то вроде этого:

#define TableViewHeight ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 916.0 : 374.0)
#define DisplayHeight ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 1024.0 : 480.0)
#define DisplayWidth ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 768.0 : 320.0)

Наконец, для DisplayHeight и DisplayWidth вам на самом деле не нужно ничего делать, и, вероятно, лучше использовать CGRectGetHeight([[UIScreen mainScreen] bounds]) и CGRectGetWidth([[UIScreen mainScreen] bounds]).

1 голос
/ 29 декабря 2011

Я думаю, что вы ответили на свой вопрос :) Однако, чтобы убрать предупреждения, почему бы не объявить их как переменные вместо макросов?

Я бы сделал это:

CGFloat tableHeight = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 916.0f : 374.0f;
1 голос
/ 29 декабря 2011

#define#ifdef и т. Д.) Обрабатываются препроцессором.Это работает полностью до самого компилятора;на самом деле это два совершенно разных процесса.Так что он вообще не взаимодействует с такими конструкциями, как if.

Ваш второй пример кода может сработать, если UIUserInterfaceIdiomPad является макросом (т.е. это был #defined).

0 голосов
/ 29 декабря 2011

Нет, к сожалению. #define используется препроцессором для замены символов перед компиляцией кода, тогда как if является частью фактического кода, подлежащего компиляции. В первом случае препроцессор ничего не знает о том, каким будет результат вашего оператора if.

Второй случай не имеет смысла, потому что вас не волнует, UIUserInterfaceIdiomPad определено, вас волнует, имеет ли UI_USER_INTERFACE_IDIOM() это значение.

0 голосов
/ 29 декабря 2011

Используйте #if вместо обычного if.

Однако это будет препроцессор, что будет означать, что ваше приложение будет просто компилироваться только для iPhone или iPad(если это даже сработало).

Итог: нет, вы не можете использовать макросы.Они проверяются при компиляции, а не при запуске приложения.

...