Ser*_*hii 8 c printf types objective-c ios
编译我的iOS应用程序的arm64代码我遇到了一个有趣的问题,与自定义Foundation类型的不同基本类型有关.假设我想printf(或stringWithFormat)一个声明为NSUInteger的数字
[NSString stringWithFormat:@"%u", _depth,
Run Code Online (Sandbox Code Playgroud)
这将为arm64生成一个警告编译,因为NSUInteger为arm64声明为unsigned long.因此,我应该用"%lu"替换"%u",但现在在编译armv7(s)体系结构时这变得无效,因为对于32位体系结构,NSUInteger声明为unsigned int.我知道警告说"NSUInteger不应该用作格式参数",所以让我们继续浮动:
typedef CGFLOAT_TYPE CGFloat;
Run Code Online (Sandbox Code Playgroud)
在64位CGFLOAT_TYPE上是双倍的,而在32位上它是浮点数.因此,做这样的事情:
- (void)foo:(CGFloat)value;
Run Code Online (Sandbox Code Playgroud)
然后
[self foo:10.0f];
[self foo:10.0];
Run Code Online (Sandbox Code Playgroud)
在编译两个体系结构时仍会产生警告.在32位架构上,第二次调用不正确(从double转换为float),在64-bt架构上,第一次将float转换为double(这是好的,但仍然不好).
很想听听你对这个问题的看法.
ipm*_*mcc 11
我见过的一种(不可否认的)方法是使用魔术#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]);
Run Code Online (Sandbox Code Playgroud)
非常可怕,但它确实有效.
另一个看似更常见的方法是在每个平台上简单地将值转换为更大的类型,如下所示:
NSString* foo = [NSString stringWithFormat:@"%lu things in the array.", (unsigned long)array.count]);
Run Code Online (Sandbox Code Playgroud)
最近(即自新的拳击速记语法出来以来)我发现自己很懒,开始只是拳击一切,像这样:
NSString* foo = [NSString stringWithFormat:@"%@ things in the array.", @(array.count)]);
Run Code Online (Sandbox Code Playgroud)
可能有更好的方法,但那些是我最常见的.
| 归档时间: |
|
| 查看次数: |
2680 次 |
| 最近记录: |