2

I'm trying to pull a random item out of an array. When I run, it works about 50/50 between pulling a random item and giving me this error "EXC_BAD_INSTRUCTION". Any idea what's going on?

Right now my code looks like this: BEFORE Solution

   func randomCard() -> Card {
    let randomIndex = Int(arc4random()) % cardArray.count
    let randomCard = cardArray[randomIndex]

    cardArray.removeAtIndex(randomIndex)

    return randomCard
}

After

   func randomCard() -> Card {

    let randomIndex = arc4random_uniform(UInt32(cardArray.count))
    let randomCard = cardArray[randomIndex.hashValue]

    cardArray.removeAtIndex(randomIndex.hashValue)

    return randomCard
}

This is what I'm using now and seems to be working.Thanks everyone for the help.

Justin Cabral
  • 565
  • 1
  • 6
  • 20
  • Are you able to determine which values of `randomIndex` work, and which ones return `EXC_BAD_INSTRUCTION`? – admdrew Jun 06 '14 at 19:52
  • Just seems to be random. It works sometimes and other times it doesn't. – Justin Cabral Jun 06 '14 at 19:55
  • Which line caused the error? Log randomIndex. – zaph Jun 06 '14 at 19:56
  • @JustinCabral To start troubleshooting, I would record the exact 'bad' values and see if you can reproduce it by manually feeding those bad values into `cardArray.removeAtIndex(` – admdrew Jun 06 '14 at 19:56
  • 2
    BTW, It is better (no bias) and easier to use arc4random_uniform(cardArray.count); – zaph Jun 06 '14 at 19:57
  • is it the removal or what happens with the randomCard after it is removed from the array? – Grady Player Jun 06 '14 at 19:57
  • The bad instruction comes on the return. @Zaph i'll use that from now on, def looks cleaner. – Justin Cabral Jun 06 '14 at 19:59
  • 2
    This sounds like [the same bug someone experienced a couple of days ago](http://stackoverflow.com/questions/24044316/using-swift-i-seem-to-get-this-error-only-sometimes-when-using-arc4random-why). You're not doing anything wrong — it's a bug in Swift, which is after all still in beta. – Chuck Jun 06 '14 at 19:59

1 Answers1

6

arc4random can return negative numbers which would cause you problems since negative % positive = negative A better approach would be to use arc4random_uniform

let randomIndex = arc4random_uniform(UInt32(cardArray.count))

EXC_BAD_INSTRUCTION seems like a bad exception to throw on a bounds error, but that does seem to be what you get.

David Berry
  • 40,941
  • 12
  • 84
  • 95