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

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

当将应用程序转换为64位时,会给出警告(当然),因为%ld %lu对于现在变成long unsigned longunsigned longtypes是预期的。

简单地转换格式说明符当然会在32位版本中引入反向警告。
所以唯一的解决办法就是使用64位的说明符,而在64位的数据types中,每个地方都会有32位的警告。

但我想知道是否有格式说明符专门为NSIntegerNSUIntegertypes,这将在两个架构上工作,而不铸造?

我认为最安全的方法是把它们放入NSNumber实例中。

 NSLog(@"Number is %@", @(number)); // use the highest level of abstraction 

这个拳击通常不需要创build一个新的对象感谢标记的指针魔术。

如果你真的不想使用NSNumber ,你可以像其他人那样手动投入原始types:

 NSLog(@"Number is %ld", (long)number); // works the same on 32-bit and 64-bit 

login到控制台时,还可以使用%zdNSInteger )和%tuNSUInteger )。

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

也可以在这里find。

,(不幸的是)没有直接对应于NS(U)Integer printf格式。 因此,对于架构独立的代码,你必须将所有东西都转换为“长”的变体(如Xcode“Fix-it”所示):

 NSInteger i = ...; NSLog(@"%ld", (long)i); 

我知道的唯一select是从编译为arm64和32位体系结构时的Foundationtypes :

 // 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); 

使用预处理器macros(但即使该答案的作者称它是一个“无可争议的方法”)。