Приложение вылетает после arc4random() с таймером?

В Swift у меня есть таймер. Каждую секунду точка на экране меняется на другое точечное изображение. Он выбирает точку, которая отображается случайным образом. Это то, что я хочу. Приложение вылетает сразу при запуске. Мол, сразу. Как этот сбой исправлен? А также после этого будет ли он работать с моим текущим кодом? После комментирования некоторых вещей и тестирования, строка, которая вызывает это, - imageNumber = Int(arc4random())%13 . Как это исправить?

Мой код выглядит следующим образом:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    var dotChangingTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("changeDot"), userInfo: nil, repeats: true)

    var theRandomImages: UIImage[] = [dotOne, dotTwo, dotThree, dotFour, dotFive, dotSix, dotSeven, dotEight, dotNine, dotTen, dotEleven, dotTwelve, dotThirteen]

    openingScreenDynamicDot = theRandomImages[Int(imageNumber)]
    let finalChangingDotWelcomePage = UIImageView(image: openingScreenDynamicDot)
    finalChangingDotWelcomePage.frame = CGRectMake(110, 234, 100, 100)
}
func changeDot() {
    println("the images should be changing...")
    imageNumber = Int(arc4random())%13

    var theRandomImages: UIImage[] = [dotOne, dotTwo, dotThree, dotFour, dotFive, dotSix, dotSeven, dotEight, dotNine, dotTen, dotEleven, dotTwelve, dotThirteen]

    openingScreenDynamicDot = theRandomImages[(imageNumber)]
}

person Benr783    schedule 14.06.2014    source источник
comment
Какую природу сбоя показывает отладчик?   -  person Tommy    schedule 14.06.2014
comment
Кроме того, сначала определите свой массив изображений и используйте счетчик в качестве операнда по модулю! Этот голый 13 просто напрашивается на неприятности.   -  person Nate Cook    schedule 14.06.2014


Ответы (2)


Вы получаете эти сбои, потому что пытаетесь преобразовать значение UInt32 в Int, не обращая внимания на проверку диапазона. Поскольку UInt32 не имеет знака, половина возможных возвращаемых значений arc4random() будет вне диапазона Int, и при попытке приведения вы получите ошибку времени выполнения. Безопасный способ сделать то, что вы делаете, - сначала взять сумму по модулю, а затем привести к Int:

imageNumber = Int(arc4random() % 13)

Однако это вводит смещение по модулю, которое влияет на случайность результата, поэтому вам лучше:

imageNumber = Int(arc4random_uniform(13))

Оба этих метода дадут вам случайные значения от 0 до 12 включительно.

person Nate Cook    schedule 14.06.2014
comment
Вариант 2 исправляет сбои. Хотя, все равно не меняет изображение каждую секунду. Что не так с моим кодом, из-за которого он не работает? - person Benr783; 14.06.2014
comment
Добавьте println(imageNumber) после его создания. Случайный не означает неповторяющийся — нередко бывает несколько одинаковых чисел подряд, если вы ждете достаточно долго. - person Nate Cook; 14.06.2014
comment
вы можете пропустить один, если вы получите повтор - person Grady Player; 14.06.2014
comment
Все еще не меняется с func changeDot() { println("the images should be changing...") var theRandomImages: UIImage[] = [dotOne, dotTwo, dotThree, dotFour, dotFive, dotSix, dotSeven, dotEight, dotNine, dotTen, dotEleven, dotTwelve, dotThirteen] imageNumber = Int(arc4random_uniform(13)) openingScreenDynamicDot = theRandomImages[(imageNumber)] } @NateCook - person Benr783; 14.06.2014
comment
Вам нужно будет обновить UIImageView новым изображением, и я не вижу, где в viewDidLoad() вы добавили UIImageView в иерархию представлений вашего контроллера представления. - person Nate Cook; 14.06.2014
comment
Я сделал UIImageView в своем представленииDidLoad, как я могу получить к нему доступ, как если бы он был глобальным @NateCook - person Benr783; 14.06.2014
comment
Объявление его внутри определения вашего класса, но вне любого метода, сделает его переменной экземпляра или сохраненным свойством — вы можете подробнее читайте здесь. - person Nate Cook; 14.06.2014
comment
Объявите это так: var finalChangingDotWelcomePage: UIImageView! и настройте так же, как в viewDidLoad() (но удалите let). Затем позвоните self.view.addSubview(finalChangingDotWelcomePage). - person Nate Cook; 14.06.2014

У меня были похожие загадочные сбои с arc4random(), и я решил их, переключившись на arc4random_uniform().

Попробуй это:

imageNumber = Int(arc4random_uniform(13))
person GRiker    schedule 14.06.2014
comment
Все еще получаю сбои. - person Benr783; 14.06.2014
comment
да, это не решило бы проблему, если бы алгоритм был правильным, в противном случае это фактически дает равномерное распределение (если вы можете настроить таргетинг на 10.что угодно, я думаю, 10.7) - person Grady Player; 14.06.2014