【问题标题】:Using #define in an "if" statement在“if”语句中使用#define
【发布时间】:2012-01-29 12:29:50
【问题描述】:

是否可以在“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

有什么想法吗?

【问题讨论】:

  • IMO,这不是常量的用途。

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


【解决方案1】:

是的,这是可能的,但它可能不会像你想的那样。在编译预处理步骤的结果之前解释预处理器指令。

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

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

【讨论】:

  • 所有四个答案实际上都是正确的,但这是唯一真正解释正确方法的答案。
【解决方案2】:

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

如果UIUserInterfaceIdiomPad 是一个宏(即它一直是#defined),您的第二个代码示例可能会起作用。

【讨论】:

    【解决方案3】:

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

    我会这样做:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        使用#if 而不是普通的if。

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

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

        【讨论】:

          【解决方案6】:

          不,很遗憾。 #define 被预处理器用于在编译代码之前替换符号,而 if 是要编译的实际代码的一部分。在第一种情况下,预处理器对 if 语句的结果一无所知。

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

          【讨论】:

            猜你喜欢
            • 2012-10-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-09-27
            • 1970-01-01
            • 2014-09-30
            • 2021-07-16
            • 2018-09-16
            相关资源
            最近更新 更多