Objective c 不应在格式字符串中使用整数?

Objective c 不应在格式字符串中使用整数?,objective-c,Objective C,这是我在《荣耀》中的代码: [NSString stringWithFormat:@"Total Properties: %d", (int)[inArray count]]; 这给了我一个Xcode 5.1警告: Values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead 好吧,我很困惑。这个值实际上是一个32位int,

这是我在《荣耀》中的代码:

[NSString stringWithFormat:@"Total Properties: %d", (int)[inArray count]];
这给了我一个Xcode 5.1警告:

Values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead

好吧,我很困惑。这个值实际上是一个32位int,我将它转换为32位int。那么它抱怨的是什么(我假设的计数),为什么这个转换不能修复它呢?

NSUInteger和NSInteger在32位(int)和64位(long)上的长度不同。为了使一个格式说明符适用于两种体系结构,必须使用long说明符并将值强制转换为long:

Type    Format Specifier    Cast
----    ----------------    ----
NSInteger    %ld            long
NSUInteger   %lu            unsigned long
例如,您的代码变成:

[NSString stringWithFormat:@"Total Properties: %lu", (unsigned long)[inArray count]];

实际上,要做的工作很少,因为Xcode的Fix-It功能会自动为您完成这项工作。

NSInteger的基本类型会根据平台的不同而变化:在32位平台上是32位无符号整数,在64位平台上是64位无符号整数

在本文中,苹果建议您执行以下操作:

为了避免根据平台使用不同的printf样式类型说明符,可以使用表3中所示的说明符。请注意,在某些情况下,可能需要强制转换值

对于
NSUInteger
使用格式
%lu
%lx
,并将值强制转换为
无符号long

因此,需要按如下方式更改代码以避免警告:

[NSString stringWithFormat:@"Total Properties: %lu", (unsigned long)[inArray count]];

也可以对CPU无关的格式字符串使用“z”和“t”修饰符,例如

NSInteger x = -1;
NSUInteger y = 99;
NSString *foo = [NSString stringWithFormat:@"NSInteger: %zd, NSUInteger: %tu", x, y];

您也可以尝试使用NSNumber方法:

[NSString stringWithFormat:@"Total Properties: %@", [[NSNumber numberWithUnsignedInteger:[inArray count]] stringValue]];

谢谢你,马特!几乎像冠军一样工作,几乎是因为修复它似乎没有修复它。好吧,你原来的int类型可能把它弄糊涂了。我只是在我的书代码中对这些行做了大量的修复(最后四到五次提交),并且修复了大部分。但是,在这两种体系结构上,NSInteger/NSUInteger的长度与long/unsigned long的长度相同。那么为什么需要演员阵容呢?@matt:我的前提是正确的。如果你认为他们错了,请指出你认为错误的陈述和你认为错误的地方。你确定这句话会产生警告吗?我自己一直在使用它们强制转换int,而且我从未出错。只是用一个简单的例子在Xcode 5.1中检查了它。为了避免将来读者的混淆:此警告的出现(或否)取决于您正在编译的体系结构。与
unsigned long
相同。那么为什么强制转换是必要的呢?@user102008因为
NSUInteger
依赖于平台。
unsigned long
@user102008也是如此,但是
unsigned long
匹配所有系统上的
%lu
,而
NSUInteger
可能匹配
%lu
%llu
,取决于系统。@user102008这是巧合。
NSUInteger
unsigned long
的大小由单独的实体控制(Cocoa库的制造商与Objective-C编译器的制造商)<代码>%lu保证始终匹配
无符号长字符
;对于
NSUInteger
,没有这样的保证,因为它属于不同的人。如果可可制造商明天决定,从下一版本开始,所有平台上的
NSUinteger
应为32位,他们可以100%做到这一点。这将在没有强制转换的情况下中断格式化代码。