我在NSLog / NSAssert等调用中有相当数量的字符串格式说明符,它们分别使用%d
和%u
NSInteger (= int on 32bit)
和NSUInteger (= unsigned int on 32bit)
类型。
将应用转换为64位时,会发出警告(当然),因为现在%ld %lu
和long
类型需要unsigned long
。
简单地转换格式说明符当然会在32位构建中引入反向警告 因此,我认为唯一可以免于警告的解决方案是使用64位说明符,并在34位值类型中转换为32位版本中的警告。
但我想知道是否有专门针对NSInteger
和NSUInteger
类型的格式说明符,这些格式说明符适用于两种架构而不进行转换?
答案 0 :(得分:59)
我认为最安全的方法是将它们装入NSNumber
个实例。
NSLog(@"Number is %@", @(number)); // use the highest level of abstraction
由于tagged pointer魔法,这拳击通常不需要创建新对象。
如果确实不想使用NSNumber
,您可以像其他人建议的那样手动投射基本类型:
NSLog(@"Number is %ld", (long)number); // works the same on 32-bit and 64-bit
答案 1 :(得分:38)
您还可以在登录控制台时使用%zd
(NSInteger
)和%tu
(NSUInteger
)。
NSInteger integer = 1;
NSLog(@"first number: %zd", integer);
NSUInteger uinteger = 1;
NSLog(@"second number: %tu", uinteger);
答案 2 :(得分:4)
否,(遗憾的是)没有与NS(U)Integer
直接对应的printf格式。
因此,对于与体系结构无关的代码,您必须将所有内容转换为“long”
变体(如Xcode“Fix-it”所示):
NSInteger i = ...;
NSLog(@"%ld", (long)i);
我所知道的唯一选择是来自Foundation types when compiling for arm64 and 32-bit architecture:
// In the precompiled header file:
#if __LP64__
#define NSI "ld"
#define NSU "lu"
#else
#define NSI "d"
#define NSU "u"
#endif
NSInteger i = ...;
NSLog(@"i=%"NSI, i);
使用预处理器宏(但即使该答案的作者也称之为 “不可否认的方法”)。