A Swift Tour로 Swift 공부하기 #8. Error Handling

minin·2021년 2월 12일
1

A Swift Tour

목록 보기
7/8

🍫 notion으로 보기
*본 포스트는 애플의 'A Swift Tour'를 바탕으로 작성되었으며, 공부하며 기록용으로 작성한 포스트이기 때문에 정확하지 않은 정보가 있을 수 있습니다!
** notion으로 작성한 문서를 임시로 올려둔 포스트이기 때문에 사진 링크의 오류와 문서의 형식 등으로 인해 보시기에 불편함이 있을 수 있습니다. (사진이 안나오거나 코드를 보기 불편한 점 등은 빠른 시일 내에 수정하도록 하겠습니다!)

8. Error Handling

에러는 Error 프로토콜을 채택adopts하는 것으로 표현한다.

//  오류 종류 정의하기
enum PrinterError: Error {
    case outOfPaper
    case noToner
    case onFire
}

**throw , throws**

  • **throw:** 에러가 발생해서 에러를 던질 때(오류를 처리하는 곳으로 전달할 때)
  • **throws:** 에러를 낼 수 있는 함수를 마크할 때

함수에서 에러를 던지고throw 싶으면, 함수는 즉시 반환을 하고 함수라고 불리던 코드는 에러를 처리handle한다.

func send(job: Int, toPrinter PrinterName: String) throws -> String{
    if PrinterName == "Never Has Toner" {
        throw PrinterError.noToner
    }
    return "Job sent"
}

do-catch

do블록: try를 사용하여 에러를 버릴 수 있는 코드를 마크한다.

catch블록: 에서 에러의 다른 이름을 주지 않으면 에러는 자동적으로 error라는 이름으로 받음.

do {
    let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")
    print(printerResponse)
} catch {
    print(error)
}
	//  PrinterName = "Bi Sheg" 이기 때문에 errorr가 나지 않고, "Job sent"가 출력된다.
	//  콘솔창: Job sent

try : 예외 상황을 다루기 위한 것. try한 메서드에 error가 발생하면 catch로 가서 처리한다.

try? try! 사용하는 것이 더 효과적이다. (← 여기에서는 do {try} catch {} 모두 적지 않아도 됨)

**experiment**

printer이름을 "Never Has Toner"로 바꾸고, 에러를 버리기 위해 send(job:toPrinter:) 함수 사용해라.

do {
	// PrinterName을 바꾸기
    let printerResponse = try send(job: 1040, toPrinter: "Never Has Toner")
    print(printerResponse)
} catch {
    print(error)
}
	//  "Never Has Toner"은 에러이기 때문에, catch로 가서 print(error)를 한다.
	//  해당 에러는 throw PrintError.**noToner**
	//  콘솔창: noToner

구체적인 에러를 처리하기 위해서 여러개의 catch 블럭을 사용할 수 있다. switch문에서의 case처럼 catch뒤에 패턴을 적어주면 된다.

do {
    let printerResponse = try send(job: 1440, toPrinter: "Gutenberg")
    print(printerResponse)
} catch PrinterError.onFire {
    print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
    print("Printer error: \(printerError).")
} catch {
    print(error)
}

	//  console: Job sent

experiment

do 블럭에 에러로 전달하는 코드를 추가하라. 첫 번째 catch블럭으로부터 에러가 처리되기 위해서 어떤 종류의 에러 코드가 필요한가? 두 번째, 세 번째 블럭은 어떠한가?

try?

에러를 처리하는 다른 방법은 결과를 optional로 전환하기 위해 try?를 사용하는 것이다. try?에서 만약 함수가 error로 전달되면, 특정 에러는 버려지고, 그 결과는 nil이 된다. 그렇지 않으면 그 결과값은 그 함수가 리턴한 값을 가진 optional이다.

let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler")
//  job sent
let printerFailure = try? send(job: 1885, toPrinter: "Never Has Toner")
//  nil

defer

defer 함수에서 모든 함수를 실행한 후에, 함수가 리턴되기 직전에 실행되는 코드를 작성하기 위해 **defer**을 사용하라. 코드는 함수가 에러로 던져졌는지와 상관없이 실행된다. setup / cleanup 코드를 작성하기 위해 defer을 사용할 수 있다. (설사 그들이 다른 시간에 실행될 필요가 있다고 하더라도)

var fridgeIsOpen = false
let fridgeContent = ["Milk", "eggs", "leftovers"]

func fridgeContains(_ food: String) -> Bool {
    fridgeIsOpen = true
    defer {
        fridgeIsOpen = false
    }
    
    let result = fridgeContent.contains(food)
    return result
}

fridgeContains("banana")  // false 반환
print(fridgeIsOpen)  //  false(defer 실행)

*.contain(element): 전달된 파라미터 값과 배열 안의 특정 원소가 일치할 경우 true반환.

let result = fridgeContent.contains(food) → "banana"가 fridgeContent에 없으므로 **false** 반환.

profile
🍫 iOS 🍫 Swift

0개의 댓글