在为 arm64 编译 iOS 应用程序的代码时,我遇到了一个有趣的问题,该问题与自定义 Foundation 类型的不同基本类型有关。假设我想 printf (或 stringWithFormat) 声明为的数字NSU整数
[NSString stringWithFormat:@"%u", _depth,
这将产生一个针对arm64编译的警告,因为NSUInteger对于arm64声明为unsigned long。因此,我应该用“%lu”替换“%u”,但现在在编译armv7架构时这变得无效,因为对于32位架构NSUInteger声明为unsigned int。
我知道警告说“NSUInteger 不应用作格式参数”,所以我们继续讨论浮动:
typedef CGFLOAT_TYPE CGFloat;
在 64 位上CGFLOAT_TYPE is double,而在 32 位上则是float。因此,做这样的事情:
- (void)foo:(CGFloat)value;
and then
[self foo:10.0f];
[self foo:10.0];
针对两种架构进行编译时仍然会产生警告。在 32 位架构上,第二个调用不正确(从 double 转换为 float),在 64 位架构上,第一个调用将 float 转换为 double(这是可以的,但仍然不好)。
很想听听您对这个问题的想法。
我见过的一种(诚然很糟糕)方法是使用魔法#define
和编译时字符串文字连接。像这样:
// In your prefix header or something
#if __LP64__
#define NSI "ld"
#define NSU "lu"
#else
#define NSI "d"
#define NSU "u"
#endif
// Then later you can use these like this...
NSString* foo = [NSString stringWithFormat:@"%"NSU" things in the array.", array.count]);
非常可怕,但它有效。
另一种看似更常见的方法是简单地将每个平台上的值向上转换为更大的类型,如下所示:
NSString* foo = [NSString stringWithFormat:@"%lu things in the array.", (unsigned long)array.count]);
最近(即自从新的拳击速记语法出现以来)我发现自己很懒并且开始只对所有内容进行拳击,如下所示:
NSString* foo = [NSString stringWithFormat:@"%@ things in the array.", @(array.count)]);
可能有更好的方法,但这些是我见过最多的方法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)