NSInteger和NSUInteger处于混合的64位/ 32位环境中

时间:2013-12-03 15:42:38

标签: ios objective-c 64-bit arm64

我在NSLog / NSAssert等调用中有相当数量的字符串格式说明符,它们分别使用%d%u NSInteger (= int on 32bit)NSUInteger (= unsigned int on 32bit)类型。

将应用转换为64位时,会发出警告(当然),因为现在%ld %lulong类型需要unsigned long

简单地转换格式说明符当然会在32位构建中引入反向警告 因此,我认为唯一可以免于警告的解决方案是使用64位说明符,并在34位值类型中转换为32位版本中的警告。

但我想知道是否有专门针对NSIntegerNSUInteger类型的格式说明符,这些格式说明符适用于两种架构而不进行转换?

3 个答案:

答案 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)

您还可以在登录控制台时使用%zdNSInteger)和%tuNSUInteger)。

NSInteger integer = 1;
NSLog(@"first number: %zd", integer);

NSUInteger uinteger = 1;
NSLog(@"second number: %tu", uinteger);

Also to be found here.

答案 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);

使用预处理器宏(但即使该答案的作者也称之为 “不可否认的方法”)。