20

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

我的按钮功能

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

我在 NSUInteger 线上看到它,我有几个类似的 stackoverflow,他们似乎在谈论 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.
}

在此处输入图像描述

4

2 回答 2

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);
于 2013-10-15T02:26:05.453 回答
11

根据我的评论,arc4random_uniform()接受并返回 a u_int32_t,一个始终为 32 位的无符号整数,无论​​目标架构如何。但是,predictionArray.count返回 an ,对于 32 位和 64 位系统NSUInteger,它的d 不同;typedefunsigned int32 位系统上是 32 位 ( ),在 64 位系统上是 64 位 ( unsigned long)。如果您在 64 位系统上运行,将 64 位传递NSUInteger给需要 32 位整数的函数将导致编译器抱怨您正在丢弃位。

于 2013-10-15T06:41:40.867 回答