【问题标题】:NSUInteger should not be used in format strings?NSUInteger 不应该用在格式字符串中吗?
【发布时间】:2014-03-26 19:36:26
【问题描述】:

这是我的全部代码:

[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 是什么(我假设的计数),为什么这个演员不能解决它?

【问题讨论】:

  • 您确定该行会产生警告吗?我自己一直使用它们强制转换为 int,而且我从来没有出错。刚刚在 Xcode 5.1 中通过一个简单的示例对其进行了检查。
  • 希望能避免未来读者的困惑:此警告是否出现(或不出现)取决于您正在编译的架构。

标签: objective-c


【解决方案1】:

NSUInteger 和 NSInteger 在 32 位 (int) 和 64 位 (long) 上的长度不同。为了使 one 格式说明符适用于 both 架构,您必须使用 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 功能会自动为您完成。

【讨论】:

  • 谢谢马特!像冠军一样几乎工作,几乎是因为修复它似乎没有修复它。
  • 嗯,你原来的 int 演员可能把它弄糊涂了。我只是在我的书代码中按照这些行进行了大量修复(最近四到五次提交在github.com/mattneub/Programming-iOS-Book-Examples),并且Fix-It 中的大部分都是正确的。但其中一些必须手工完成。
  • 但是,NSInteger/NSUInteger 在两种架构上的长度都与 long/unsigned long 相同。那么为什么需要演员阵容呢?
  • @matt:我的前提是正确的。如果您认为他们是错误的,请指出您认为哪个陈述是错误的以及您认为它有什么问题。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    NSUInteger 的底层类型因平台而异:在 32 位平台上为 32 位无符号整数,在 64 位平台上为 64 位无符号整数。

    Platform Dependencies section on of the String Programming GuideApple 建议您执行以下操作:

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

    对于NSUInteger,使用格式%lu%lx,并将值转换为unsigned long

    因此您的代码需要更改如下以避免警告:

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

    【讨论】:

    • unsigned long 相同。那么为什么需要演员阵容呢?
    • @user102008 因为NSUInteger 是平台相关的。
    • unsigned long也是如此
    • @user102008 但是unisgned long在所有系统上都匹配%lu,而NSUInteger可能匹配%lu%llu,具体取决于系统。
    • @user102008 这是一个巧合。 NSUIntegerunsigned long 的大小由不同的实体控制(Cocoa 库的制造商与 Objective-C 编译器的制造商)。 %lu 保证始终匹配 unsigned longNSUInteger 没有这样的保证,因为它属于不同的人。如果 Cocoa 制造商明天决定从下一个版本开始,NSUinteger 在所有平台上应该是 32 位,他们可以 100% 做到这一点。这会在没有强制转换的情况下破坏格式化代码。
    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-19
      • 2022-10-14
      • 2012-05-12
      • 2017-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多