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

Leo*_*ban 20 warnings compiler-errors objective-c ios

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

我的按钮功能

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

我在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.
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Die*_*Epp 68

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

NSUInteger index = arc4random_uniform((uint32_t) predictionArray.count);
Run Code Online (Sandbox Code Playgroud)

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

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

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

assert(predictionArray.count <= (uint32_t) -1);
Run Code Online (Sandbox Code Playgroud)

  • 那不是我的意图.你已经得到了一个upvote和Leon标记你的答案是正确的 - 只要留下评论(1)会留下你的答案作为规范,即使它是不完整的,我的评论是有效的.(2)有些人在强行编辑答案时采取极端冒犯行为,我无意冒犯任何人.(3)如果你的答案已被标记为正确,根据经验,即使我提出了更完整的答案,提问者也可能会忽略它.(4)所以我选择礼貌地建议你扩大你的答案.就这样. (11认同)
  • Deitrich,我不想编辑你的答案并踩到脚趾,但我可能会扩展它来解释*为什么*演员是必要的.@LeonGaban`arc4random_uniform()`接收并返回一个`uint32_t`,一个始终为32位的无符号整数,与目标体系结构无关.但是,`predictionArray.count`返回一个`NSUInteger`,对于32位和64位系统,它是`typedef`d; 它在32位系统上为32位,在64位系统上为64位.如果你在64位系统上运行,传入一个64位的"NSUInteger"将导致编译器抱怨你丢弃了一些位. (4认同)

Ita*_*ber 11

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