본문 바로가기

IOS

swift - 오류처리 Error Handling by yagom

728x90
반응형

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

 

enum 오류종류이름: Error{

  case 종류1

  case 종류2

  case 종류3

  ...

}

 

// 자판기 동작 오류의 종류를 표현한 VendingMachineError 열거형
enum VendingMachineError: Error{
	case invalidInput
	case insufficientFunds(moneyNeeded: Int)
    case outOfStock
}

// 함수에서 발생한 오류 던지기

// 자판기 동작 도중 발생한 오류 던지기
// 오류 발생의 여지가 있는 메서드는 throws를 사용하여 오류를 내포하는 함수임을 표시한다.
class VendingMachine {
	let itemPrice: Int = 100
    var itemCount: Int = 5
    var deposited: Int = 0
    
    // 돈 받기 메서드
    func receiveMoney(_ money: Int) throws{
    
    	// 입력한 돈이 0이하면 오류를 던진다.
        guard money > 0 else {
        	throw VendingMachineError.invalidInput
        }
        
        // 오류가 없으면 정상처리를 한다.
        self.deposited += money
        print("\(money)원 받음")
    }
    
    // 물건 팔기 메서드
    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(moenyNeeded: moeny)
        }
        
        // 구매하려는 수량보다 요구하는 수량이 많으면 오류를 던진다.
        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, try?, try!

 

do-catch

오류발생의 여지가 있는 throws 함수(메서드)는 do-catch 구문을 활용하여 오류발생에 대비한다.

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

do {
	try machine.receiveMoney(300)
} catch /*(let error)*/ { // 전달인자를 적지 않더라도 자동으로 error 변수에 들어간다.

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

do{ // 간결하게 표현
	result = try mathine.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에 nil이 저장됨
result // Optional("2개 제공함")

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

try!인 경우

오류가 발생하지 않을 것이라는 강력한 확신을 가질 때 try!를 사용하면 정상동작 후에 바로 결과값을 돌려받습니다. 오류가 발생하면 런타임 오류가 발생하여 애플리케이션 동작이 중지된다.

 

result = try! machine.vend(numberOfItems: 1)
result // 1개 제공함, 오류가 발생하면 die

 

반응형

'IOS' 카테고리의 다른 글

IOS, Swift, Xcode를 배우기 시작하면서  (0) 2023.01.10
swift - 고차함수 by yagom  (1) 2023.01.10
swift - 익스텐션 extension by yagom  (0) 2023.01.10
swift - 프로토콜 by yagom  (0) 2023.01.10
swift - assert와 guard by yagom  (0) 2023.01.10