【问题标题】:How to define a preprocessor macro that uses another as a conditional?如何定义使用另一个作为条件的预处理器宏?
【发布时间】:2016-11-18 02:53:39
【问题描述】:

我有一个游戏,它使用一些常见的宏来确定用户使用的是什么设备:

#define IS_IPAD      (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE    (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_4  (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 480.0f)
#define IS_IPHONE_5  (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0f)
#define IS_IPHONE_6  (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0f)
#define IS_IPHONE_6P (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0f)

这是一个较老的游戏,我只是想用一个乘数调整一些定位。宏是理想的:

#ifdef IS_IPHONE_6
#define SIZEMOD 1.172f
#elif IS_IPHONE_6P
#define SIZEMOD 1.6875f
#else
#define SIZEMOD 1.0f
#endif

不幸的是,这会检查是否定义了宏 IS_IPHONE_6,这将始终为真,因此在其他设备上使用了错误的乘数。如何使用宏正确定义SIZEMOD

【问题讨论】:

  • 请停止为此使用宏。请写出正确的函数。内联函数不会比宏慢,但实际上可读和可调试。
  • 这不是一个“我应该使用宏”的问题。宏很有用。我是唯一的开发者。我已经在整个代码中使用了宏。我不会维护这段代码,也不会再碰它。如果我在几年后再次触及它,我宁愿为那个乘数添加另一个宏,而不是去挖掘源代码。
  • 好吧,我看不出内联函数在挖掘源代码方面与该宏有何不同。你的问题的解决方案是不要使用宏,因为它不起作用。您根本无法在编译时获取设备类型。您必须为此编写一个函数。
  • 使用这些宏的代码编写不正确。计算应该基于运行时视图的大小,而不是对设备模型的一些检查。无论将来有什么新的屏幕大小的设备可用,代码都应该按原样工作,无需更改代码。那么在 iPad 上处理多任务呢? iPad 应用程序必须处理多种可能的尺寸。
  • 老实说,有些人对此很狂热。你对这个项目一无所知。有时可以使用宏。并非所有东西都是一个简单的实用应用程序,它具有可以无限延伸的极简 UI。有时人们编写的游戏依赖于相对特定的设备条件。

标签: ios objective-c macros


【解决方案1】:

我希望我不会因为这个而被下地狱?

#define IS_IPAD      (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE    (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_4  (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 480.0f)
#define IS_IPHONE_5  (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0f)
#define IS_IPHONE_6  (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0f)
#define IS_IPHONE_6P (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0f)

#define (SIZEMOD IS_IPHONE_6 ? 1.172f : IS_IPHONE_6P ? 1.6875f : 1.0)

【讨论】:

  • 啊。没想到你可以像这样链接三元运算符。
  • 只是一个简短的说明 - 您必须将定义括在括号中。否则,如果您说诸如 x = y+100*SIZEMOD; 之类的操作,操作顺序可能会做一些疯狂的事情;
【解决方案2】:

我更好的方法是使用适当的功能。这是我经常使用的东西,它运行良好并且支持所有已知的 iOS 模型。

https://github.com/duhovny/DeviceHardware

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    相关资源
    最近更新 更多