3

In objective c we use try catch to stop crashing e.g.

- (void)viewDidLoad {
[super viewDidLoad];

tableData = [NSArray arrayWithObjects:@"Egg Benedict", @"Mushroom Risotto", @"Full Breakfast", @"Hamburger", @"Ham and Egg Sandwich", @"Creme Brelee", @"White Chocolate Donut", @"Starbucks Coffee", @"Vegetable Curry", @"Instant Noodle with Egg", @"Noodle with BBQ Pork", @"Japanese Noodle with Pork", @"Green Tea", @"Thai Shrimp Cake", @"Angry Birds Cake", @"Ham and Cheese Panini", nil];



@try {
    NSLog(@"%@",tableData[1000]);
     } @catch (NSException *exception) {
    NSLog(@"%@",exception);
  }  
 }

But when I am using swift 3 , warning showing and application crashed

enter image description here

Can anyone explain, how can i stop this. I read some topics from google but couldn't understand. Can any one help me out.

Hamish
  • 78,605
  • 19
  • 187
  • 280
Udai kumar
  • 233
  • 2
  • 17
  • 5
    Swift's `try - catch` expression does **not** catch exceptions, it does catch explicitly `throw`n errors. Improve your code to avoid raising exceptions. – vadian Jul 15 '17 at 09:38
  • Possible duplicate of [try-catch exceptions in Swift](https://stackoverflow.com/questions/24023112/try-catch-exceptions-in-swift) – vadian Jul 15 '17 at 09:39
  • Possible duplicate of [How do I catch "Index out of range" in Swift?](https://stackoverflow.com/questions/37222811/how-do-i-catch-index-out-of-range-in-swift) – Hamish Jul 15 '17 at 10:27

2 Answers2

0

Swift arrays implement a subscript for easier access of its members. Subscripts cannot throw. You can either implement an extension to the Collection protocol and create a throwing function that gets the member if the index is below the (.count-1) of the Colllection, or throws an error if it's above.

Alternatively you can implement a subscript that returns a constant, and then guard against that constant, and throw an error in the else statement of the guard (but unless you're having try statements in that do block, it'll be a bit of syntactical fat).

Theis Egeberg
  • 2,556
  • 21
  • 30
0

You can achieve it in simple steps, kindly check this out:

// define your array
let array : [String] = ["One","Two"]

// define your array error
enum ArrayError : Error {
        case OutOfBoundsError(String)
}

// this method will return if its a valid or invalid value for array index.
private func getValueForIndex(index:Int)->String?{

    if array.count > index && index >= 0{
        return array[index]
    }else {
        return nil
    }

}

You can handle it with try and catch easily by using guard let to throw error into the catch block as the following:

    do {

        guard let index1 = try getValueForIndex(index: 0) else { throw ArrayError.OutOfBoundsError("Out of bounds for \(0)") }
        guard let index2 = try getValueForIndex(index: 1) else { throw ArrayError.OutOfBoundsError("Out of bounds for \(1)") }
        guard let index3 = try getValueForIndex(index: 2) else { throw ArrayError.OutOfBoundsError("Out of bounds for \(2)") }
        guard let index4 = try getValueForIndex(index: 3) else { throw ArrayError.OutOfBoundsError("Out of bounds for \(3)") }

    } catch{

        print(error)

    }

This is work around, there are many other ways and might be complicated by i kept it simple. Let me know if it works for you !

AaoIi
  • 8,288
  • 6
  • 45
  • 87
  • This answer is pretty counter-intuitive. The getValueForIndex() function should be marked with throws, and should throw from the else instead of manually throwing inside the do. – user1898712 Feb 28 '18 at 17:38
  • he need try catch a function, not a returned function? – kemdo Aug 01 '18 at 09:34