user1.develop
user1.develop

Reputation: 15

Swift 3 - [__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 .. 2]

I've a 14 button and I've got action to my buttons and in the action is animate, I've a words String composed 2 characters 3, 4, ... 10 characters,so when I clicked 3 button it's correct no problem but when I clicked 4th button get me a crash and the message is:

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

How to solve this crash ??

This my code:

class QuestionView: UIViewController {

    var nsmutableArray1: NSMutableArray = []
    var nsmutableArray2: NSMutableArray = []
    var nsmutableArray3: NSMutableArray = []
    var nsmutableArray4: NSMutableArray = []

    var i : Int = 0

    func animateButton(sender: UIButton) {

        let xS = nsmutableArray1.object(at: i) as? Int ?? 0
        var yS = nsmutableArray2.object(at: i) as? Int ?? 0
        let widthS = nsmutableArray3.object(at: i) as? Int ?? 0
        let heightS = nsmutableArray4.object(at: i) as? Int ?? 0
        yS -= widthS

        let startS = CGPoint(x: xS, y: yS)
        let sizeS = CGSize(width: widthS, height: heightS)

        sender.frame = CGRect(x: startS.x, y: startS.y, width: sizeS.width, height: sizeS.width)

        UIView.animate(withDuration: 2, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 6, options: .allowUserInteraction, animations: { [weak self] in

            sender.transform = .identity

            self?.i += 1

        }) { (finished) in

           }
    }

}

Upvotes: 0

Views: 1475

Answers (1)

Woof
Woof

Reputation: 1383

Highly recommend you to use Swift arrays:

var array1: [Int] = []

Or

var array1: [CGFloat] = [] //you can use any type here

stored var means that this array can be changed (mutable)

This crash means that the index of the object you are trying to get is out of arrays range (your array doesn't contain any object at that index).

Remember that array indexes started from 0, it means that to access to the first object, you should use:

array1[0]

Same way if your array contains four objects and you want to get an objects at index 3, setting this:

 array1[3] //will access to the fourth object(the last one) in this array

So first you need to detect what index are you sending to array and detect how many objects arrays have. Use:

array1.count

This will return a count of object array contains. Also you can use this parameter to avoid crashes:

if i < array1.count {
    //this index is in the array range use it to access to the object
    let xS = array1[i]
}else{
   //this index is out of the array range, using it will cause a crash

   //make a print of this array to detect why this array doesn't contain on object at this index (if it should contain)
    print(array1)
}

Or just set your var to 0 before checking an array if it doesn't matter to have a value in the array or not, like this:

var xS = 0

 if i < array1.count {
        //this index is in the array range use it to access to the value
        xS = array1[i]
 }

//if array doesn't contain an object at that index, you won't have any changes for that var, at it will be equal 0

Upvotes: 0

Related Questions