2013-10-15 30 views
19

在树形教程之后,我在XCode中看到这个流行的Object-C警告消息。目标c隐式转换失去整数精度'NSUInteger'

我的按钮功能

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

我看到它在NSUInteger行,我已经很少几个类似stackoverflows的,他们似乎谈论32位VS 64位数字和类型转换,但不知道如何在这里做?

我predictionArray

- (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

回答

67

您可以放心地抑制了投警告。

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

这并不总是安全镇压警告,所以直到你找出操作是否安全不要去铸造的东西摆脱警告。

这里发生了什么事情在你的平台上是一个64位整数类型的typedef。它不是总是 64位,只是在某些平台上。编译器警告你,有些位被扔掉了。如果你知道这些位不重要,你可以使用一个强制转换。

在这种情况下,结果是index将始终低于2 -1。如果predictionArray甚至可能包含2 或更多元素,则您的程序出现错误,您必须构建一个64位版本的arc4random_uniform()。你可以确保这一点与下面的代码:

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

嗯,我只是试过这个,但仍然是相同的警告。那么,我将NSUInteger铸造成什么? “(NSUInteger)”是什么意思。或者更重要的是,它警告我的是什么? –

+0

@LeonGaban:我把剧组放在了错误的地方。 –

+0

谢谢!仍然试图理解这一点,所以'NSUInteger'总是一个32位的int?我试图将它转换为64位并得到相同的错误。那些东西对我来说是新鲜的,从来没有碰到过它。 –

11

按我的意见,arc4random_uniform()发生在,并返回,一u_int32_t,无符号整数,始终是32位,而不管目标架构。但是,对于32位和64位系统,predictionArray.count返回NSUInteger,即typedefd;它在32位系统上是32位(unsigned int),在64位系统上是64位(unsigned long)。如果您在64位系统上运行,则将64位NSUInteger传递给期望32位整数的函数会导致编译器抱怨您丢掉了位。

+0

感谢您的解释,所以如果我发送一个32位数字到一个64位函数/方法是否会减慢程序?或者它只是说我可以更高效。是否有一个64位版本的'arc4random_uniform()'?或者我应该使用'u_int32_t'很多? –

+1

@LeonGaban如果有的话,一个不明显的数量。您的32位数字必须扩展为64位;如果它是无符号的,那么它会自动扩展为0,如果它是有符号的并且是负数,它将会延长1s。这不是一个真正的问题。但是,如果您尝试将64位数字传递到32位函数中,则部分数字可能会被抛出(该函数只能得到较低的32位),并且编译器会抱怨(这就是为什么您必须向你保证,你知道你在演员中所做的事情)。 –

+0

@LeonGaban不幸的是,没有64位版本的'arc4random *'函数,但是继续投射它们,你会没事的。我建议不要在每个地方使用'u_int32_t',因为根据定义,它是32位的。 'NSUInteger'有一个优势,就是苹果为你匹配目标平台的'typedef'd,所以你可以随时使用它,并知道你正在有效地做事(你不想任意限制你的尺寸数据除非它是有道理的并且是必要的)。 –

相关问题