Подтвердить что ты не робот

Объективное с неявное преобразование теряет целую точность "NSUInteger"

Следуя руководству по treehouse, я вижу это популярное предупреждающее сообщение Object-C в XCode.

Моя кнопка

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

Я вижу это в строке NSUInteger, у меня мало таких похожих стековых потоков, и они, похоже, говорят о 32-битных и 64-битных числах и типе каста, но не уверены, как это сделать здесь?

My 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

4b9b3361

Ответ 1

Вы можете безопасно подавить предупреждение с помощью трансляции.

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

Не всегда безопасно подавлять предупреждения, поэтому не оставляйте вещи, чтобы избавиться от предупреждений, пока не выясните, безопасна ли операция.

Что здесь происходит, так это то, что NSUInteger есть на вашей платформе typedef для 64-битного целочисленного типа. Это не всегда 64 бит, как раз на некоторых платформах. Компилятор предупреждает вас, что некоторые из этих бит отбрасываются. Если вы знаете, что эти биты неважны, вы можете просто использовать трансляцию.

В этом случае результат состоит в том, что index всегда будет меньше 2 32 -1. Если даже возможно, чтобы predictionArray содержал 2 32 или больше элементов, тогда ваша программа имеет ошибку, и вам придется построить 64-разрядную версию arc4random_uniform(). Вы можете обеспечить это следующим кодом:

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

Ответ 2

В соответствии с моим комментарием arc4random_uniform() принимает и возвращает u_int32_t целое число без знака, которое всегда равно 32 битам, независимо от целевой архитектуры. Однако predictionArray.count возвращает NSUInteger, который typedef d по-разному для 32-битной и 64-битной систем; это 32 бита (unsigned int) в 32-битной системе и 64-битные (unsigned long) в 64-разрядной системе. Если вы работаете в 64-разрядной системе, передача в 64-разрядную NSUInteger функции, ожидающей 32-разрядного целого, заставит компилятор жаловаться на то, что вы выбрасываете биты.