itisjustK
코딩과 사람 사는 이야기
itisjustK
전체 방문자
오늘
어제
  • 분류 전체보기 (207)
    • 일이삼사오육칠팔구십일이삼사오육칠팔구십일이삼사오육칠.. (0)
    • Web (43)
      • html & css (9)
      • django & python (15)
      • java script (9)
    • iOS (51)
      • Swift (42)
      • SwiftUI (5)
    • CS (25)
      • 자료구조 (6)
      • 운영체제 (3)
      • 데이터베이스 (9)
      • 네트워크 (7)
    • PS (34)
      • 알고리즘 & 자료구조 (0)
    • Life (36)
    • Retrospective (15)
    • Book (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 어플
  • 개발자
  • AppleDevloperAcademy
  • 점주
  • 독립서점
  • 생활코딩 #이고잉 #HTML #코딩 #개발자
  • crud
  • mongodb
  • ios
  • binding
  • POSTECH
  • CS
  • 킨디
  • SwiftUI
  • 생활코딩
  • 연결리스트
  • nosql
  • SWIFT
  • CoreData
  • 세그멘테이션

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
itisjustK

코딩과 사람 사는 이야기

iOS/Swift

[iOS 프로그래밍을 위한 스위프트 기초] Ch3. 오류처리 및 고차함수 - 28. 오류 처리

2021. 7. 30. 15:54

오류 처리

- 스위프트에서 오류(Error)는 Error라는 프로토콜을 준수하는 타입의 값을 통해 표현

- Error 프로토콜은 사실상 요구사항이 없는 빈 프로토콜일 뿐이지만, 오류를 표현하기 위한 타입(주로 열거형)은 이 프로토콜을 채택

- 스위프트의 열거형은 오류의 종류를 나타내기에 아주 적합

- 연관 값을 통해 오류에 관한 부가 정보를 제공할 수도 있음

 

Error 프로토콜과 주로 열거형을 통해서 요류를 표현한다

enum 오류종류 이름: Error {
    case 종류1
    case 종류2
    case 종류3
    ...
}

 

자판기 오류 예시

enum VendingMachineError: Error {
    case invalidInput
    case insufficientFunds(moneyNeeded: Int)
    case outOfStock
}

 

자판기 구현

- 오류 발생의 여지가 있는 메소드는 throws를 사용하여 오류를 내포하는 함수임을 표시

//자판기 오류 종류
enum VendingMachineError: Error {
    case invalidInput
    case insufficientFunds(moneyNeeded: Int)
    case outOfStock
}

class VendingMachine {
    let itemPrice: Int = 100
    var itemCount: Int = 5
    var deposited: Int = 0
    
    //돈 투입 메소드
    func insertMoney(money: Int) throws {  //throws: 오류 발생 시 오류를 던진다는 뜻
        
        //  투입한 돈이 0 이하면 오류를 던진다
        guard money > 0 else {
            throw VendingMachineError.invalidInput
        }
        
        //오류가 없으면 정상 처리
        self.deposited += money
        print("\(money)원 투입")
    }
    
    //물건 팔기 메소드
    //guard문을 통해서 오류를 하나씩 설정해주었다
    func vend(numberOfItems numberOfItemsToVend: Int) throws -> String {
        
        //원하는 아이템의 수량이 잘못 입력되었으면 오류를 던짐
        guard numberOfItemsToVend > 0 else {
            throw VendingMachineError.invalidInput
        }
        
        // 구매하려는 수량보다 미리 넣어둔 돈이 적으면 오류를 던집니다
        guard numberOfItemsToVend * itemPrice <= deposited else {
            let moneyNeeded: Int
            moneyNeeded = numberOfItemsToVend * itemPrice - deposited
            
            throw VendingMachineError.insufficientFunds(moneyNeeded: moneyNeeded)
        }
        
        // 구매하려는 수량보다 요구하는 수량이 많으면 오류를 던집니다
        guard itemCount >= numberOfItemsToVend else {
            throw VendingMachineError.outOfStock
        }
        
        // 오류가 없으면 정상처리를 합니다
        let totalPrice = numberOfItemsToVend * itemPrice
        
        self.deposited -= totalPrice
        self.itemCount -= numberOfItemsToVend
        
        return "\(numberOfItemsToVend)개 제공함"
    }
}

// 자판기 인스턴스
let machine: VendingMachine = VendingMachine()

// 판매 결과를 전달받을 변수
var result: String?

 

 

 

오류 처리

- 던져진 오류를 처리하기 위한 코드도 작성해야함.

- 오류 발생의 여지가 있는 throws 메소드는 try를 사용하여 호출해야함. try와 do-catch, try?와 try! 에 대해서도 알아야 함

 

do-catch ( 오류 발생에 대비 )

- 오류 발생의 여지가 있는 메소드에 대해 do-catch 구문을 활용하여 오류 발생에 대비

- 가장 정석적인 방법. 모든 오류 케이스에 대응

do {
    try machine.insertMoney(money: 0)
} catch VendingMachineError.invalidInput {
    print("입력이 잘못되었습니다")
} catch VendingMachineError.insufficientFunds(let moneyNeeded) {
    print("\(moneyNeeded)원이 부족합니다")
} catch VendingMachineError.outOfStock {
    print("수량이 부족합니다")
} // 입력이 잘못되었습니다

 

catch를 하나씩 쓰기 귀찮다면 switch를 이용하는 방법도 있다

do {
    try machine.insertMoney(money: 300)
} catch /*(let error)*/ {
    
    switch error {
    case VendingMachineError.invalidInput:
        print("입력이 잘못되었습니다")
    case VendingMachineError.insufficientFunds(let moneyNeeded):
        print("\(moneyNeeded)원이 부족합니다")
    case VendingMachineError.outOfStock:
        print("수량이 부족합니다")
    default:
        print("알수없는 오류 \(error)")
    }
} // 300원 받음

 

케이스별로 오류처리할 필요가 없으면 catch 구문 내부를 간략화해도 무방

do {
    result = try machine.vend(numberOfItems: 4)
} catch {
    print(error)
} // insufficientFunds(100)

또는

do {
    result = try machine.vend(numberOfItems: 4)
}

 

 

try? & try!

  • try?

- 별도의 오류처리 결과를 통보받지 않고 오류가 발생했으면 결과값을 nil로 돌려받을 수 있음

- 정상동작 후에는 옵셔널 타입으로 정상 반환값을 돌려 받음

result = try? machine.vend(numberOfItems: 2)
result // Optional("2개 제공함")

result = try? machine.vend(numberOfItems: 2)
result // nil

 

 

  • try!

- 오류가 발생하지 않을 것이라는 강력한 확신을 가질 때 try!를 사용하면 정상동작 후에 바로 결과값을 돌려받음

- 오류가 발생하면 런타임 오류가 발생하여 애플리케이션 동작이 중지됨

result = try! machine.vend(numberOfItems: 1)
result // 1개 제공함

//result = try! machine.vend(numberOfItems: 1)
// 런타임 오류 발생!

'iOS > Swift' 카테고리의 다른 글

[iOS 앱 프로그래밍] 음원 재생기 애플리케이션 - 애플리케이션 만들기 (1)  (0) 2021.08.04
[iOS 프로그래밍을 위한 스위프트 기초] Ch3. 오류처리 및 고차함수 - 29. 고차함수  (0) 2021.08.01
[iOS 프로그래밍을 위한 스위프트 기초] Ch2. 다양한 표현 및 확장 - 27. 익스텐션  (0) 2021.07.30
[iOS 프로그래밍을 위한 스위프트 기초] Ch2. 다양한 표현 및 확장 - 26. 프로토콜  (0) 2021.07.29
[iOS 프로그래밍을 위한 스위프트 기초] Ch2. 다양한 표현 및 확장 - 25. assert / guard  (0) 2021.07.29
    'iOS/Swift' 카테고리의 다른 글
    • [iOS 앱 프로그래밍] 음원 재생기 애플리케이션 - 애플리케이션 만들기 (1)
    • [iOS 프로그래밍을 위한 스위프트 기초] Ch3. 오류처리 및 고차함수 - 29. 고차함수
    • [iOS 프로그래밍을 위한 스위프트 기초] Ch2. 다양한 표현 및 확장 - 27. 익스텐션
    • [iOS 프로그래밍을 위한 스위프트 기초] Ch2. 다양한 표현 및 확장 - 26. 프로토콜
    itisjustK
    itisjustK

    티스토리툴바