在“if”语句中使用#define

时间:2011-12-28 22:15:29

标签: ios objective-c c-preprocessor conditional-compilation

是否可以在“if”语句中使用#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 个答案:

答案 0 :(得分:7)

是的,这是可能的,但它可能不符合您的想法。在编译预处理步骤的结果之前解释预处理程序指令。

这意味着所有的预处理程序指令都被解释,重新定义了一些宏,然后编译剩余的代码,如下所示。

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

换句话说,在预处理之后,您只有空ifelse个身体。

如果要根据运行时的条件更改某些内容的值,那么某些内容必须是真正的对象,而不仅仅是预处理器宏。 E.g。

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 :(得分:1)

#define(和#ifdef等)由预处理器处理。这完全在之前编译器本身运行;它们实际上是两个完全独立的过程。所以它根本不与if等构造进行交互。

如果UIUserInterfaceIdiomPad是一个宏(即它是#defined),那么您的第二个代码示例可能会有效。

答案 2 :(得分:1)

我认为你回答了自己的问题:)但是,为了删除这些警告,为什么不将它们声明为变量而不是宏呢?

我会这样做:

CGFloat tableHeight = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 916.0f : 374.0f;

答案 3 :(得分:1)

在编译器运行之前,

#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])

答案 4 :(得分:0)

使用#if代替普通if

然而这将是一个预处理器的事情,这意味着你的应用程序只会编译为iPhone或iPad(如果它甚至工作)。

底线:不,你不能使用宏。在编译时检查它们,而不是在运行应用程序时检查它们。

答案 5 :(得分:0)

不,不幸的是。预编译器使用#define在编译代码之前替换符号,而if是要编译的实际代码的一部分。在第一种情况下,预处理器不知道if语句的结果是什么。

第二种情况没有意义,因为你不关心UIUserInterfaceIdiomPad 已定义,您关心UI_USER_INTERFACE_IDIOM()是否具有该值。