在32位和64位体系结构上格式化NS(U)Integer时types转换的替代方法?
使用64位版本的iOS,我们不能再使用%d和%u来格式化NSInteger和NSUInteger 。 因为对于64位,这些是typedef'd long和unsigned long而不是int和unsigned int 。 
所以如果你尝试用%d格式化NSInteger,Xcode会抛出警告。 Xcode对我们来说很好,并为这两种情况提供了一种替代scheme,它由l前缀格式说明符和longtypes组成。 那么我们的代码基本上是这样的:
 NSLog(@"%ld", (long)i); NSLog(@"%lu", (unsigned long)u); 
如果你问我,这是一个痛苦的眼睛。
 几天前,Twitter上有人提到了格式说明符%zd来格式化签名variables和%tu来格式化32和64位平台上的无符号variables。 
 NSLog(@"%zd", i); NSLog(@"%tu", u); 
这似乎工作。 而我更喜欢types化。
但我真的不知道为什么这些工作。 现在这两个对我来说基本上都是神奇的价值。
 我做了一些研究,发现z前缀表示以下格式说明符与size_t具有相同的大小。 但是我完全不知道前缀t是什么意思。 所以我有两个问题: 
  %zd和%tu究竟是什么意思? 
 是否可以安全地使用%zd和%tu而不是Applebuild议将types转换为long? 
  我知道类似的问题和苹果64位转换指南,这些指南都推荐使用%lu (unsigned long)方法。  我要求一个替代types铸造。 
从http://pubs.opengroup.org/onlinepubs/009695399/functions/printf.html :
-   ž 
 指定以下转换说明符适用于size_t或相应的带符号整数types参数;
-   Ť 
 指定以下转换说明符适用于ptrdiff_t或相应的无符号types参数;
从http://en.wikipedia.org/wiki/Size_t#Size_and_pointer_difference_types :
-   size_t用于表示特定实现中任何对象(包括数组)的大小。 它用作sizeof运算符的返回types。
-   ptrdiff_t用来表示指针之间的差异。
在当前的OS X和iOS平台上
 typedef __SIZE_TYPE__ size_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; 
 其中__SIZE_TYPE__和__PTRDIFF_TYPE__由编译器预定义。 对于编译器定义的32位 
 #define __SIZE_TYPE__ long unsigned int #define __PTRDIFF_TYPE__ int 
和编译器定义的64位
 #define __SIZE_TYPE__ long unsigned int #define __PTRDIFF_TYPE__ long int 
(这可能在Xcode版本之间有所变化,受@ user102008评论的启发,我已经用Xcode 6.2检查过了,并且更新了答案。)
 所以ptrdiff_t和NSInteger都是typedef'd 相同的types : int在32位和long在64位。 因此 
 NSLog(@"%td", i); NSLog(@"%tu", u); 
在所有当前的iOS和OS X平台上正常工作并编译时不会出现警告。
  size_t和NSUInteger在所有平台上都有相同的大小,但是它们不是相同的types,所以 
 NSLog(@"%zu", u); 
实际上在编译32位时会发出警告。
 但是这个关系在任何标准上都是不固定的(据我所知),所以我不认为这是安全的(就像假设long与指针的大小一样不被认为是安全的)。 它可能在未来破裂。 
我所知道的唯一types转换的替代方法是使用预处理器macros从“ 编译为arm64和32位体系结构时的基础types ”的答案:
 // 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); 
 我宁愿只是使用一个NSNumber : 
 NSInteger myInteger = 3; NSLog(@"%@", @(myInteger)); 
这在所有情况下都不起作用,但是我用上面的代替了大部分NS(U)Integer格式。
 根据构build32位像64位 ,另一种解决scheme是定义NS_BUILD_32_LIKE_64macros,然后你可以简单地使用%ld和%lu说明符与NSInteger和NSUInteger没有铸造和没有警告。