objective c隐式转换失去整数精度'NSUInteger'

时间:2013-10-15 02:23:20

标签: ios objective-c compiler-errors warnings

在关于树屋的教程之后,我在XCode中看到了这个流行的Object-C警告消息。

我的按钮功能

- (IBAction)buttonPressed:(UIButton *)sender {
    NSUInteger index = arc4random_uniform(predictionArray.count);
    self.predictionLabel.text = [predictionArray objectAtIndex:index];
}

我在NSUInteger线上看到它,我有几个类似的堆栈溢出,他们似乎谈论32位对64位数字和类型转换,但不知道该怎么做呢?

我的预测阵营

- (void)viewDidLoad
{
    [super viewDidLoad];
    predictionArray = [[NSArray alloc] initWithObjects:
                   @"It is certain", @"It is decidely so", @"All signs say YES", @"The stars are not aligned",
                   @"My reply is no",
                   @"It is doubtful",
                   @"Better not tell you now",
                   @"Concentrate and ask again",
                   @"Unable to answer now", nil];
// Do any additional setup after loading the view, typically from a nib.
}

enter image description here

2 个答案:

答案 0 :(得分:68)

您可以使用强制转换来安全地抑制警告。

NSUInteger index = arc4random_uniform((uint32_t) predictionArray.count);

并不总是安全来抑制警告,所以在你弄清楚操作是否安全之前,不要去除掉警告。

这里发生的是NSUInteger在您的平台上是64位整数类型的typedef。它只是在某些平台上总是 64位。编译器警告你,其中一些位被丢弃了。如果您知道这些位不重要,您可以使用强制转换。

在这种情况下,结果是index总是低于2 32 -1。如果predictionArray甚至可以远程包含2个 32 或更多元素,那么您的程序有错误,您将不得不构建一个64位版本的arc4random_uniform() 。您可以使用以下代码确保这一点:

assert(predictionArray.count <= (uint32_t) -1);

答案 1 :(得分:11)

根据我的评论,arc4random_uniform()接收并返回一个u_int32_t,一个始终为32位的无符号整数,与目标架构无关。但是,predictionArray.count会返回NSUInteger,对于32位和64位系统,typedef会有所不同;它在32位系统上为32位(unsigned int),在64位系统上为64位(unsigned long)。如果您在64位系统上运行,则将64位NSUInteger传递给期望32位整数的函数将导致编译器抱怨您丢弃了位。