이번에는 오류 처리르 위한 try-catch에 대해서 확인을 해보려고 한다.
try-catch
- 프로그램 내에서 에러가 발생한 상황에 대해 이를 복구하는 과정
- 런타임 에러가 발생한 경우 발생(Throwing) / 감지(catching) / 전파(propagating) / 조작(manipulating)을 지원하는 1급 클래스를 제공한다.
프로그램에서 개발자가 원하는데로 모든 기능이 제대로 작동한다고 100% 장담할 수 없다.
예를 들어 디스크에 파일을 저장하는 것을 생각해보면, 디스크의 용량이 꽉차서 파일을 저장 못할 수도 있고, 쓰기 권한이 없어서 파일을 저장할 수가 없을 수도 있다.
이렇게 파일을 디스크에 저장하는 간단한 기능에도 오류가 발생할 수 있는 가능성이 여럿 존재한다.
오류 처리 기능을 통해 이런 상황들을 구별하여 프로그램 자체적으로 오류를 해결할 수도 있고, 사용자에게 어떤 오류가 발생하였는지 알려줄 수 있다.
추가적으로 스위프트에서 에러는 에러 프로토콜을 따르는 타입의 값으로 표현된다.
에러 프로토콜은 요구사항이 없는 빈 프로토콜이지만, 에러를 표현하기 위해서는 해당 프로토콜을 채택해야한다.
스위프트 열거형은 오류 원인을 나누고 해당 오류의 특성에 대한 모델을 만드는데 적합하다.
오류 처리를 위한 CarError 열거형을 선언하였다. 열거형 이름 선언 후 : Error를 사용할 경우 Error 프로토콜을 채택했다는 내용이다.
tire_pressure(tireLevel : Int)는 타이어의 공기압이 얼마나 남았는지 알려주기 위해서 tireLevel이라는 Int형 연관값을 사용할 예정이다.
이렇게 열거형을 통해서 오류의 종류를 표현하는 것이 가장 일반적인 방법이다.
필자의 경우 타이어 공기압이 적을 경우 에러를 발생시킬 것이며, 오류가 발생하면 정상적인 실행을 계속 할 수 없다는 것을 나타낸다.
이렇게 throw 구문을 이용하여 에러가 발생할 것 같은 지점에 에러를 던져주면 된다.
오류를 던질 수도 있지만 오류가 던져진 것에 대비하여 던져진 오류를 처리하기 위한 코드도 작성을 해야한다.
예를들어 던져진 오류가 무엇인지 판단하여 다른 방법으로 문제 해결을 시도해본다던지 사용자에게 오류를 알리는 등의 코드를 작성해야 한다.
Swift에서 오류를 처리하는 방법은 4자기가 있다.
- 함수에서 발생하는 오류를 해당 함수를 호출한 코드에 전파하는 방법
- do - catch 구문을 이용해서 오류를 처리하는 방법
- 옵셔날 값으로 오류를 처리하는 방법
- 오류가 발생하지 않을 것이라고 확신하는 방법
이렇게 4가지가 있다.
첫 번째 방법인 오류가 발생할 수 있음을 나타내기 위해서는 함수, 매개변수, 생성자 매개변수 뒤에 이처럼 throws를 작성해주면 된다.
이렇게 오류가 붙은 함수를 쓰로잉 함수라고 한다.
필자의 경우에는 타이어 공기압이 낮을 경우 guard 문을 통해서 에러를 표출하도록 진행을 했고, 타이어 공기압이 30 아래일 경우에 에러가 나도록 진행을 했다.
쓰로잉 함수는 함수 내부에서 쓰로우가 되는 오류를 함수가 호출된 곳으로 전파한다. 쓰로잉 함수만 에러를 전파할 수 있다.
추가적으로 이전에 guard를 확인했다 싶이 guard문은 false 일 때에 else 구문이 실행되고, 함수가 조기 종료 된다.
위의 guard문이 걸리지 않을 경우 공기압 양호를 반환하면서 종료가 되도록 구현을 해놨다.
평상시의 함수를 사용할 때처럼 일반적인 함수 호출을 진행해봤지만, 이렇게 Call can throw but is not marked with 'try' 에러가 발생했다.
첫 번째 방법으로 쓰로잉 함수를 통해서 이렇게 오류를 던질수도 있다는 것을 확인하였고, 이 메소드를 사용하기 위해서는 try를 사용하라는 error가 발생한 내용이다.
첫 번째 방법과 두 번째 방법과 연관이 됨으로 do-catch나 try를 사용한 오류 처리에 대해서 추가적으로 내용 확인을 해보도록 하자.
함수 메소드 생성자들에서 오류를 던져주면 오류 발생을 전달받은 코드블럭은 do-catch 구문을 사용해서 오류를 처리해주어야한다.
do절 내부에서 오류를 던지고, catch절에서 오류를 전달받아 예외처리를 진행하면 된다.
do-catch 구문의 사용 방법은 아래와 같다.
do { try 오류 발생 가능성 코드 } catch 오류 패턴 { 처리 코드 } |
그럼 코드를 통해서 위에서 만든 checkTirePressure 함수를 사용해보도록 하자.
do 구문에 사용하고자 하는 쓰로잉 함수를 명시했다. 그리고 이후에 에러가 발생하는 내용에 대해서는 catch문에 각각 에러의 내용을 작성해두었다.
tireLevel 이 -101 부터인 인경우에는 타이어가 터진 내용으로 작성을 하였고, 나머지는 공기압 부족, 이외의 에러인 경우에는 그 외의 에러가 발생했습니다. 문구를 표기하도록 진행을 하였다.
catch 만 작성한 코드 블럭은 오류의 종류를 생성하지 않아도 코드 블럭을 생성하면 블록 내부에 암시적으로 에러라는 이름의 지역 상수가 오류 내용으로 들어오게 된다.
해당 코드의 실행 결과 "타이어 공기압 부족 : 10" 이 표기된다는 것을 코드의 실행을 통해서 알 수가 있다.
이번에는 3번째 방법인 옵셔널 값으로 오류를 처리하는 방법에 대해서 확인을 진행해보자.
상수 status를 만들었고, try?를 사용하여 발생하는 해당 내용을 옵셔널 값으로 처리를 진행하도록 했다.
위의 사진은 에러가 발생하지 않은 내용이기 때문에 위의 checkTirePressure에서 정의한 대로 공기압 양호 : 30 이 표기가 되었다.
그럼 이제 에러를 발생하도록 tireLevel 의 Int를 바꿔보자.
아래의 status2같은 경우에는 오류가 발생했음으로 해당 값이 nil로 된 내용을 확인할 수 있다.
이처럼 try만을 사용해서 쓰로잉 함수를 사용하고 싶을 경우에는 함수 이름 앞에 try?를 붙여주면 된다.
함수가 에러를 던지기 때문에 nil이 된다.
그럼 try!에 대해서 확인해보도록 하자.
try!를 사용하였을 때에는 try?와 마찬가지로 에러가 발생될 것 같은 함수의 이름에 try!를 붙여주면 된다.
옵셔널에서 !는 강제라고 확인을 하였다. 이처럼 try!는 쓰로잉 함수나 메소드가 에러를 던져주지 않을 것이라고 확실할 때에만 사용한다.
코드를 작성하는 개발자가 오류를 던질 수 있는 함수 즉, 쓰로잉 함수 또는 메소드를 호출할 때에 오류가 절대로 발생하지 않을 것이라고 확신할때만 사용한다.
만약 위에 처럼 checkTirePressure(tireLevel : 10 )을 했을때에는 쓰로잉 함수에서 에러가 발생함으로 try!를 쓴 상태에서 에러가 발생할 경우에는 런타임 에러가 발생하여 프로그램이 강제종료 된다.
이처럼 Swift에서는 오류를 처리하는 다양한 방법을 제공한다.
에러가 발생했을 때에 예외처리를 해줘야하는 상황에서 아주 유용하게 사용할 수 있다.
'APPLE > Swift 문법' 카테고리의 다른 글
[ 기초 문법 ] 고차함수 ( map, filter, reduce ) (0) | 2022.08.25 |
---|---|
[ 기초 문법 ] Closure (0) | 2022.08.24 |
[ 기초 문법 ] 옵셔널 체이닝 (0) | 2022.08.23 |
[ 기초 문법 ] 열거형 (0) | 2022.08.22 |
[ 기초 문법 ] Extension (0) | 2022.08.22 |