Mat*_*uch 53 printf objective-c nsinteger ios
随着iOS版的64位版本,我们不能使用%d和%u再格式化NSInteger和NSUInteger.因为对于64位,这些是typedef'd long而unsigned long不是int和unsigned int.
因此,如果您尝试使用%d格式化NSInteger,Xcode将发出警告.Xcode对我们很好,并提供了这两种情况的替代品,它包括一个带有l前缀的格式说明符和一个长的类型转换.然后我们的代码基本上是这样的:
NSLog(@"%ld", (long)i);
NSLog(@"%lu", (unsigned long)u);
Run Code Online (Sandbox Code Playgroud)
如果你问我,这是一个痛苦的眼睛.
几天前,Twitter上有人提到格式说明符%zd来格式化签名变量和%tu在32位和64位平台上格式化无符号变量.
NSLog(@"%zd", i);
NSLog(@"%tu", u);
Run Code Online (Sandbox Code Playgroud)
这似乎有效.而且我更喜欢类型转换.
但老实说,我不知道为什么这些工作.现在两者对我来说基本上都是神奇的价值观.
我做了一些研究,并发现z前缀意味着以下格式说明符具有相同的大小size_t.但我完全不知道前缀是什么t意味着.所以我有两个问题:
究竟是什么%zd和%tu意味着什么呢?
是否可以安全使用%zd,%tu而不是苹果建议长期使用?
我知道类似的问题和Apples 64位过渡指南,它们都推荐这种%lu (unsigned long)方法.我要求替代铸造.
Mar*_*n R 52
来自http://pubs.opengroup.org/onlinepubs/009695399/functions/printf.html:
size_t或对应的有符号整数类型参数;ptrdiff_t或相应的无符号类型参数;从http://en.wikipedia.org/wiki/Size_t#Size_and_pointer_difference_types:
size_t用于表示特定实现中任何对象(包括数组)的大小.它用作sizeof运算符的返回类型.ptrdiff_t 用于表示指针之间的差异.在当前的OS X和iOS平台上我们有
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
Run Code Online (Sandbox Code Playgroud)
其中__SIZE_TYPE__和__PTRDIFF_TYPE__由编译器中预定义.对于32位编译器定义
#define __SIZE_TYPE__ long unsigned int
#define __PTRDIFF_TYPE__ int
Run Code Online (Sandbox Code Playgroud)
对于64位编译器定义
#define __SIZE_TYPE__ long unsigned int
#define __PTRDIFF_TYPE__ long int
Run Code Online (Sandbox Code Playgroud)
(这可能在Xcode版本之间发生了变化.由@ user102008的评论激发,我已经用Xcode 6.2检查了这个并更新了答案.)
因此ptrdiff_t,NSInteger它们都是相同类型的 typedef :
int在32位和long64位上.因此
NSLog(@"%td", i);
NSLog(@"%tu", u);
Run Code Online (Sandbox Code Playgroud)
在所有当前的iOS和OS X平台上正常工作并在没有警告的情况下进行编译.
size_t并且NSUInteger在所有平台上具有相同的大小,但它们的类型不同,所以
NSLog(@"%zu", u);
Run Code Online (Sandbox Code Playgroud)
实际上在编译32位时会发出警告.
但是这个关系在任何标准中都没有固定(据我所知),因此我
不认为它是安全的(与假设long与指针大小相同并不被认为是安全的意义相同).它可能在未来破裂.
我所知道的唯一的类型转换替代方法是使用预处理器宏来回答" 编译arm64和32位架构时的基础类型 ":
// In your prefix header or something
#if __LP64__
#define NSI "ld"
#define NSU "lu"
#else
#define NSI "d"
#define NSU "u"
#endif
NSLog(@"i=%"NSI, i);
NSLog(@"u=%"NSU, u);
Run Code Online (Sandbox Code Playgroud)
Sco*_*ets 11
我更喜欢用一个NSNumber代替:
NSInteger myInteger = 3;
NSLog(@"%@", @(myInteger));
Run Code Online (Sandbox Code Playgroud)
这并不适用于所有情况,但我用上面的代码替换了我的大多数NS(U)整数格式.
| 归档时间: |
|
| 查看次数: |
7894 次 |
| 最近记录: |