-
에러처리 (Error Handling)

(1) 에러처리 문법
에러 처리(Error Handling)란?
- 프로그램 내에서 에러가 발생한 상황에 대해 대응하고 이를 복구하는 과정📌 (런타임) 에러 처리가 왜 필요할까?
프로세스 중에서, 예외적인 상황(에러)이 발생하는 것이 미리 가능성 등을 처리해 놓으면 앱이 무작정 꺼지는 것을 예방할 수 있음 (에러 발생 가능) 함수 ⇒ 함수 실행 시에 조금 다르게 처리해야 함(에러 처리)
⭐️ 앱이 정상 작동하지 않는 경우에 사용자에게 최소한 최악의 사용자 경험을 제공하지 않기 위함코드 예시
func doSomething(num: Int) throws -> Bool { if num >= 8 { return true } else { if num < 0 { throw 에러 } return false } } doSomething(num: 8)에러는 열거형(enum)이다. 따라서 에러를 던지기 전에 먼저 정의를 해야한다.
* Swift에서 만든 Error 프로토콜을 채택 (에러를 정의하기 위함) enum SomeError: Error { case aError case bError case cError }* 에러를 던지기 if num < 0 { throw SomeError.aError }* 그래서 에러처리는 3단계로 분류될 수 있습니다.
에러처리 3단계 과정
- 에러 정의(case)
- 에러 함수 정의(에러가 발생할 수 있는)
- 에러 함수 실행
* 1) 에러 정의 , 에러 프로토콜 채택 enum WeightError: Error { case maxWeight case minWeight } * 2) 에러 함수 정의 func checkWeight(weight: Int) throws -> Bool { if weight > 90 { throw WeightError.maxWeight } else if weight < 50 { throw WeightError.minHeight } else { if weight >= 70 { return true } else { return false } } } * 3) 에러 함수 실행 do { let isChecked = try checkWeight(weight: 40) print("이용 가능: \(isChecked)") } catch { print("놀이기구 타는 것 불가능") }✅ do 블록 : 함수를 통한 정상적인 처리의 경우 실행하는 블록
⛔️ catch 블록: 함수가 에러를 던졌을 경우 실행하는 블록
(2) 에러를 처리하는 방법
에러를 처리하는 방법에는 try 키워드가 존재합니다.
try 의미 : "어떤 함수가 오류를 발생시킬 수 있는데 한번 시도라도 해볼까?"의 의미입니다.
그래서 try 선언으로 끝나지 않고 do-catch문으로 감싸주고 오류를 처리하게 됩니다.
3가지 타입 : try | try? | try!1) 에러 정식 처리 방법 - try
📚 모든 에러발생의 예외적인 경우를 디테일하게 처리 가능
do { let data = try parsing() } catch { ... }2) 옵셔널 에러 처리 방법 - try?
📚 결국 옵셔널 타입으로 리턴하기에 unwrapping 하여 사용
정상적인 경우 ⇒ (함수의) 리턴타입
에러 발생 ⇒ nil (에러 대신 nil 반환)let data = try? parsing()3) try!
📚 에러가 발생할 가능성이 없는 경우 제한적으로 사용
정상적인 경우 ⇒ (함수의)리턴타입
에러 발생 ⇒ 에러 발생let data = try! parsing()📝 rethrows 키워드
에러를 던지는 throwing 함수를 파라미터로 받은 경우, 내부에서 에러를 다시 던지기 가능 함수를 파리미터로 직접적으로 사용할 때에는 에러를 다시 던지기 위해 rethrows 키워드 사용
func someFunc(callback: () throws -> Void) rethrows {
try callback() // 에러를 다시 던짐 (직접 던지지 못함)
// throw(x)
}
(3) Defer문
📚 할 일을 미루는 defer문
함수나 메서드에서 코드의 흐름과 상관없이 가장 마지막에 실행되는 블록(지연 블록)defer 문은 4가지의 특성이 존재합니다.
1️⃣ defer 문은 작성된 위치와 순서에 상관없이 함수가 종료되기 직전에 실행
func deferFunc() { print("1") defer { print("2") } print("3") } deferFunc() // 1 // 3 // 22️⃣ defer 문을 읽기 전에 함수의 실행이 종료될 경우 defer문은 실행되지 않음
func deferFunc() { print("1") return defer { print("2") } print("3") } deferFunc() // 13️⃣ 하나의 함수나 메서드 내에서 defer 문을 여러 번 사용 가능. 이때는 가장 마지막에 작성된 defer 문부터역순으로 실행
func deferFunc() { print("1") defer { print("2") } defer { print("3") } print("4") } deferFunc() // 1 // 4 // 3 // 24️⃣ defer 문을 중첩해서 사용할 수 있다. 이때는 바깥쪽 defer 문부터 실행, 이후 가장 안쪽에 있는 defer 문은 마지막에 실행
func deferFunc() { print("1") defer { print("2") defer { print("3") } } print("4") } deferFunc() // 1 // 4 // 2 // 3❓ 그래서 defer문을 사용하는 이유
🧑🏻💻 실무에서 한 함수의 코드의 양이 방대해진 경우 ⇒ 마지막에 어떤 실행을 파악하기 위함.
( 오류가 발생하더라도 반드시 실행되어야 하는 작업을 위해 사용할 수 있음 )
참고자료
'Swift > 문법' 카테고리의 다른 글
[Swift]⭐️클래스의 상속과 초기화⭐️ (0) 2024.02.16 [Swift] 🌱 열거형(Enumeration) 기본기 (0) 2024.01.24 [Swift] 삼항연산자 그리고 범위연산자 내용 정리 (0) 2024.01.11 댓글