28

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

将应用程序转换为 64 位时,这会发出警告(当然),正如%ld %lu现在变成longandunsigned long类型所预期的那样。

简单地转换格式说明符当然会在 32 位构建中引入反向警告。
因此,我看到的唯一没有警告的解决方案是使用 64 位说明符,并将 32 位构建中出现警告的任何地方都转换为 64 位值类型。

但是我想知道是否可能有专门针对NSIntegerandNSUInteger类型的格式说明符,它们可以在两种架构上工作而无需强制转换?

4

3 回答 3

61

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

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

由于标记指针魔术,这种装箱通常不必创建新对象。

如果您真的不想使用NSNumber,您可以手动转换原始类型,如其他人建议的那样:

NSLog(@"Number is %ld", (long)number); // works the same on 32-bit and 64-bit
于 2013-12-03T21:30:50.750 回答
38

您还可以在登录控制台时使用%zd( NSInteger) 和%tu( )。NSUInteger

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

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

也可以在这里找到。

于 2014-04-14T10:49:53.127 回答
4

,(不幸的是)没有直接对应的 printf 格式NS(U)Integer。因此,对于与架构无关的代码,您必须将所有内容都转换为“长”变体(正如 Xcode“Fix-it”所建议的那样):

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

我知道的唯一替代方法是在为 arm64 和 32 位架构编译时来自 Foundation 类型

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

使用预处理器宏(但即使是该答案的作者也称其为“公认的糟糕方法”)。

于 2013-12-03T16:08:09.520 回答