NSRangeException и arc4random

Итак, я использую arc4random для получения случайного изображения из массива, код для этого выглядит следующим образом:

//ray is the array that stores my images
int pic = arc4random() % ray.count; 
tileImageView.image = [ray objectAtIndex:pic-1];
NSLog(@"Index of used image: %d", pic-1);

Я вызываю этот код несколько раз, и какое-то время он работает, но через некоторое время всегда падает из-за этой ошибки:

 *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** - [__NSArrayM objectAtIndex:]: index 4294967295 beyond bounds [0 .. 39]'

Мой вопрос в том, почему создано это смехотворно большое число? Что-то не так с функцией arc4random? Любая помощь будет принята с благодарностью


person kopproduction    schedule 15.10.2011    source источник


Ответы (3)


arc4random возвращает либо 0, либо кратное ray.count. Поэтому, когда вы изменяете его с помощью ray.count, вы получаете 0. Затем вы вычитаете из этого 1, получая -1, что преобразуется в очень большое целое число без знака.

person Chuck    schedule 15.10.2011
comment
Ах, большое спасибо! Так что правильный способ сделать это будет int pic = arc4random() % (ray.count -1);, нет? - person kopproduction; 16.10.2011
comment
@kopproduction: если вы хотите вернуть случайный элемент из массива, вам не нужно ничего вычитать. Оператор модуля уже гарантирует, что индекс меньше, чем ray.count. - person Chuck; 16.10.2011

Вы также можете использовать функцию arc4random_uniform(upper_bound) для генерации случайного числа в диапазоне. Следующее будет генерировать число от 0 до 73 включительно.

arc4random_uniform(74)

arc4random_uniform(upper_bound) избегает смещения по модулю, как описано на странице руководства:

arc4random_uniform() will return a uniformly distributed random number less than upper_bound. arc4random_uniform() is recommended over constructions like ``arc4random() % upper_bound'' as it avoids "modulo bias" when the upper bound is not a power of two.
person Himanshu A Jadav    schedule 15.10.2011

Проблема в том, что ваша конструкция pic-1 генерирует -1 один раз на некоторое время (что равно 4294967295 в беззнаковой форме). Вам нужно избавиться от pic-1 и просто использовать вместо него pic.

person interrupt    schedule 15.10.2011