192

我正在做一些练习,并收到一条警告,指出:

隐式转换失去整数精度:“NSUInteger”(又名“unsigned long”)到“int”

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    @autoreleasepool {

        NSArray *myColors;

        int i;
        int count;

        myColors = @[@"Red", @"Green", @"Blue", @"Yellow"];

        count = myColors.count; //  <<< issue warning here

        for (i = 0; i < count; i++)

        NSLog (@"Element %i = %@", i, [myColors objectAtIndex: i]);
    }

    return 0;
}

截屏

4

4 回答 4

479

在 64 位 OS X 平台上返回, 和的count方法NSArrayNSUInteger

  • NSUInteger定义为unsigned long,并且
  • unsigned long是一个 64 位无符号整数。
  • int是一个 32 位整数。

int一个比 更“小”的数据类型,因此NSUInteger是编译器警告。

另请参阅“基础数据类型参考”中的NSUInteger :

在构建 32 位应用程序时,NSUInteger 是一个 32 位无符号整数。64 位应用程序将 NSUInteger 视为 64 位无符号整数。

要修复该编译器警告,您可以将局部count变量声明为

NSUInteger count;

或者(如果你确定你的数组永远不会包含超过2^31-1元素!),添加一个显式转换:

int count = (int)[myColors count];
于 2013-06-04T13:19:34.440 回答
24

与 Martin 的回答相反,转换为 int (或忽略警告)并不总是安全的,即使您知道您的数组没有超过 2^31-1 个元素。编译为 64 位时不会。

例如:

NSArray *array = @[@"a", @"b", @"c"];

int i = (int) [array indexOfObject:@"d"];
// indexOfObject returned NSNotFound, which is NSIntegerMax, which is LONG_MAX in 64 bit.
// We cast this to int and got -1.
// But -1 != NSNotFound. Trouble ahead!

if (i == NSNotFound) {
    // thought we'd get here, but we don't
    NSLog(@"it's not here");
}
else {
    // this is what actually happens
    NSLog(@"it's here: %d", i);

    // **** crash horribly ****
    NSLog(@"the object is %@", array[i]);
}
于 2014-07-30T23:16:17.013 回答
6

更改项目中的键 > 构建设置“对 printf/scanf 的类型检查调用

解释: [它是如何工作的]

检查对 printf 和 scanf 等的调用,以确保提供的参数具有适合指定格式字符串的类型,并且格式字符串中指定的转换是有意义的。

希望它有效

其他警告

目标c隐式转换将整数精度'NSUInteger'(又名'unsigned long')丢失为'int

更改键“隐式转换为 32Bits 类型 > 调试 > *64 架构:否

[注意:可能会使 64 位架构转换的其他警告无效]

于 2015-01-21T09:48:02.740 回答
3

对“int”进行显式转换可以解决我的问题。我遇到过同样的问题。所以:

int count = (int)[myColors count];
于 2016-09-12T11:42:49.670 回答