Swift3(스위프트3)

swift3 스위프트3 오류처리 throws

알통몬_ 2017. 7. 14. 10:05
반응형


공감 및 댓글은 포스팅 하는데

 아주아주 큰 힘이 됩니다!!

포스팅 내용이 찾아주신 분들께 

도움이 되길 바라며

더 깔끔하고 좋은 포스팅을 

만들어 나가겠습니다^^

 


이번 포스팅에서는 오류처리에 대해 공부합니다.


오류를 표현하는 방법은 Error Protocol 과 (주로) 열거형을 통해서 오류를 표현합니다.


ex)

enum 오류종류이름 : Error {

   case 오류종류1

   case 오류종류2

   case 오류종류3

   ...

}


예제) 피자 자판기에서 동작할 수 있는 오류의 종류를 표현한 enum

enum MachineError : Error {

   case notEnoughMoney ( moneyNeed : Int )

   case beSoldOut

   case invalidInput

}


* 함수에서 오류가 발생했을 때 발생한 오류처리

 - 피자 자판기에서 발생한 오류 처리

  => 오류 발생 가능성이 있는 함수는 throws 를 사용해서 오류를 내포하는 함수임을 명시합니다.


class PizzaMachine {

   let price : Int = 5000

   var pizzaCount : Int = 3

   var balance : Int = 0

   

   func receiveMoney(money : Int) throws {

      // 입력한 금액이 0일 경우 오류 처리

      guard money > 0 else {

         throw MachineError.invalidInput

      }

      // 오류가 발생하지 않으면 정상 처리

      self.balance = self.balance + money

      print("\(money) 원을 넣으셨습니다")

   }


   // 피자 판매 함수

   func cookPizza( count orderPizzaCount : Int ) throws -> String {

      guard orderPizzaCount > 0 else {

         // 주문한 갯수가 0개 이하일 경우

         throws MachineError.invalidInput

      }

      // 돈이 부족할 경우

      guard orderPizzaCount * price <= balance else {

         let needMoney : Int

         needMoney = orderPizzaCount * price - balance

         throws MachineError.notEnoughMoney(moneyNeed : needMoney)

      }

      // 주문한 갯수보다 남은 갯수가 적을 경우 

      guard pizzaCount >= orderPizzaCount else {

         throws MachineError.beSoldOut

      }

     // 위 언급한 오류들이 발생하지 않고 정상동작할 경우

      let sumPrice = orderPizzaCount * price

      self.balance = self.balance - sumPrice

      self.pizzaCount = self.pizzaCount - orderPizzaCount

      return ("\(orderPizzaCount) 개의 피자를 구매하셨습니다. 요리하는데 10분 정도 소요됩니다.")

   }

}


let pizzaMachine : PizzaMachine = PizzaMachine()

var orderResult : String? // 모든 결과를 전달받을 변수


// 함수 호출 시 오류 발생의 여지가 있을 경우

try, try?, try! 를 사용해 호출해야 합니다.

그리고 do - catch 구문을 활용해서 오류 발생에 대비합니다.

- try 사용

방법 1

do {

   try pizzaMachine.receiveMoney(0)

} catch MachineError.invalidInput {

   print("잘못된 입력입니다")

} catch MachineError.notEnoughMoney(let needMoney) {

   print("\(needMoney) 원이 부족합니다")

} catch MachineError.beSoldOut {

   print("품절입니다")

}


방법 2

do {

   try pizzaMachine.receiveMoney(9000)

} catch let error {

   switch error {

   case MachineError.invalidInput :

      print("잘못된 입력입니다")

   case MachineError.notEnoughMoney(let needMoney) :

      print("\(needMoney) 원이 부족합니다")

   case MachineError.beSoldOut :

      print("품절입니다")

   default :

      print("알 수 없는 오류입니다")

}

위 방법들이 너무 복잡하다면 아래 두 방법을 사용가능하지만 썩 좋아 보이진 않습니다.

do {

   orderResult = try pizzaMachine.cookPizza(count : 1)

} catch {

   print(error)

}

or

do {

   orderResult = try pizzaMachine.cookPizza(count : 1)

}


- try? 사용

// 별도의 오류 처리 결과를 통보 받지 않고, 오류가 발생했을 경우 결과 값을 nil 로 돌려받을 수 있습니다.

// 정상 동작하였다면 Optional 타입으로 정상 반환 값을 돌려받습니다.

orderResult = try? pizzaMachine.cookPizza(count : 1)

orderResult //Optional("1개의 피자를 구매하셨습니다. 요리하는데 10분 정도 소요됩니다.")

order result = try? pizzaMachine.cookPizza(count : 1)

orderResult // nil


- try! 사용

// 만약 내가 짠 코드가 너무 완벽해서 오류가 절대로 발생하지 않을 것이라는 강한 확신이 있을 경우

try! 를 사용하면 정상 동작 후 바로 결과 값을 돌려받고 혹시라도 오류가 발생한다면,

런탄임 오류가 발생해서 애플리케이션 자체의 동작이 중지됩니다.

orderResult = try! pizzaMachine.cookPizza(count : 1)

orderResult //Optional("1개의 피자를 구매하셨습니다. 요리하는데 10분 정도 소요됩니다.")

//orderResult = try! pizzaMachine.cookPizza(count : 1) => 실행할 경우 애플리케이션 중지됨

반응형