티스토리 뷰
1. 오류처리란
- 오류처리는 프로그램이 오류를 일으켰을 때, 감지하고 회복하는 일련의 과정
2. 오류의 표현
- 스위프트에서 오류는 Error라는 프로토콜을 준수하는 타입의 값을 통해 표현
- Error는 요구사항 없는 빈 프로토콜
- 오류를 표현하기 위한 타입은 이 프로토콜을 채택함(주로 열거형)
//스마트폰에서 발생할 수 있는 에러
enum phoneError: Error {
case notConnectedToInternet
case notSupportedOnDevice
case outOfMemory
}
- 위 코드에서 Error 프로토콜을 채택한 것을 통해 오류처리를 위한 열거형임을 알 수 있음
- 오류의 종류를 예상하고, 오류 때문에 다음에 행할 동작이 정상적으로 진행되지 않으면 오류를 던져줌
- 오류를 던져줄 때는 throw 구문 사용
3.오류 포착 및 처리
- 오류를 던질 수 있지만, 그 오류를 처리하기 위한 코드가 필요함
- 오류를 처리하기 위한 네가지 방법
- 함수에서 발생한 오류를 해당 함수를 호출한 코드에 알리기
- do-catch 사용
- 옵셔널 값으로 오류 처리
- 오류가 발생하지 않을 것이라고 확신
- 함수에서 발생한 오류 알리기
- 함수에서 발생한 오류를 해당 함수를 호출한 코드에 알리는 방법
- try 키워드로 던져진 오류를 받을 수 있음(try, try!, try? 등)
- 함수, 메서드, 이니셜라이저의 매개변수 뒤에 throws 키워드로 오류를 던질 수 있음
- func cannotThrowErrors() → String // 기본
- func cannotThrowErrors() throws → String // 오류 던지기
- 아래의 예제
- 오류가 발생했을 때 제어를 위해 gaurd를 사용
- 조건이 충족되지 않으면 throw를 통해 오류를 알림
- 오류를 던질 수 있는 함수, 메서드, 이니셜라이저를 호출하는 코드는 반드시 오류를 처리할 수 있는 구문을 작성해주어야 함
- 그러나 아래 코드는 알려주기만 할 뿐 처리할 수 있는 코드가 없음
enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeed: Int)
case outOfStock
}
struct Item {
var price: Int
var count: Int
}
class VendingMachine {
var inventory = [
"Candy Bar": Item(price: 12, count: 7),
"Chips": Item(price: 10, count: 4),
"Biscuit": Item(price: 7, count: 11)
]
var coinsDeposited = 0
func dispense(snack: String) {
print("\(snack) 제공")
}
func vend(itemNamed name: String) throws {
guard let item = self.inventory[name] else {
throw VendingMachineError.invalidSelection
}
guard item.count > 0 else {
throw VendingMachineError.outOfStock
}
guard item.price <= self.coinsDeposited else {
throw VendingMachineError.insufficientFunds(coinsNeed: item.price - self.coinsDeposited)
}
self.coinsDeposited -= item.price
var newItem = item
newItem.count -= 1
self.inventory[name] = newItem
self.dispense(snack: name)
}
}
let favoriteSnacks = [
"soul": "Chips",
"model": "Biscuit",
"bom": "Chocolate"
]
func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
let snackName = favoriteSnacks[person] ?? "Candy Bar"
try vendingMachine.vend(itemNamed: snackName)
}
struct PurchasedSnack {
let name: String
init(name: String, vendingMachine: VendingMachine) throws {
try vendingMachine.vend(itemNamed: name)
self.name = name
}
}
let machine: VendingMachine = VendingMachine()
machine.coinsDeposited = 30
var purchase: PurchasedSnack = try PurchasedSnack(name: "Biscuit", vendingMachine: machine) // Biscuit 제공
print(purchase.name) // Biscuit
print("---")
for (person, favoriteSnack) in favoriteSnacks {
print(person, favoriteSnack)
try buyFavoriteSnack(person: person, vendingMachine: machine)
}
//model Biscuit
//Biscuit 제공
//soul Chips
//Chips 제공
//bom Chocolate
//Playground execution terminated: An error was thrown and was not caught:
//__lldb_expr_139.VendingMachineError.invalidSelection << 오류 발생
- do-catch 구문을 이용해서 오류처리
- 기본적인 do-catch 구문
- 위의 코드를 do-catch 을 처리, 오류를 다시 던지지 않아도 되게 되었음
//a. 기본적인 do-catch 구문
do {
try <#오류 발생 코드#>
<#오류가 발생하지 않으면 실행할 코드#>
} catch <#오류 패턴1#> {
<#처리 코드#>
} catch <#오류 패턴#> where <#추가 조건#> {
<#처리 코드#>
}
import Foundation
enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeed: Int)
case outOfStock
}
struct Item {
var price: Int
var count: Int
}
class VendingMachine {
var inventory = [
"Candy Bar": Item(price: 12, count: 7),
"Chips": Item(price: 10, count: 4),
"Biscuit": Item(price: 7, count: 11)
]
var coinsDeposited = 0
func dispense(snack: String) {
print("\(snack) 제공")
}
func vend(itemNamed name: String) throws {
guard let item = self.inventory[name] else {
throw VendingMachineError.invalidSelection
}
guard item.count > 0 else {
throw VendingMachineError.outOfStock
}
guard item.price <= self.coinsDeposited else {
throw VendingMachineError.insufficientFunds(coinsNeed: item.price - self.coinsDeposited)
}
self.coinsDeposited -= item.price
var newItem = item
newItem.count -= 1
self.inventory[name] = newItem
self.dispense(snack: name)
}
}
let favoriteSnacks = [
"soul": "Chips",
"model": "Biscuit",
"bom": "Chocolate"
]
func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
let snackName = favoriteSnacks[person] ?? "Candy Bar"
// try vendingMachine.vend(itemNamed: snackName)
tringVend(itemNamed: snackName, vendingMachine: vendingMachine)
}
struct PurchasedSnack {
let name: String
init(name: String, vendingMachine: VendingMachine) { // throws {
// try vendingMachine.vend(itemNamed: name)
tringVend(itemNamed: name, vendingMachine: vendingMachine)
self.name = name
}
}
func tringVend(itemNamed name: String, vendingMachine: VendingMachine) {
do {
try vendingMachine.vend(itemNamed: name)
} catch VendingMachineError.invalidSelection {
print("ERROR: \(name) is not vaild")
} catch VendingMachineError.outOfStock {
print("ERROR: Out of Stock")
} catch VendingMachineError.insufficientFunds(let coinsNeeded) {
print("ERROR: Coins is not enough. Please insert \(coinsNeeded)coin more.")
} catch {
print("OTHER ERROR")
}
}
let machine: VendingMachine = VendingMachine()
machine.coinsDeposited = 20
//var purchase: PurchasedSnack = try PurchasedSnack(name: "Biscuit", vendingMachine: machine) // Biscuit 제공
var purchase: PurchasedSnack = PurchasedSnack(name: "Biscuit", vendingMachine: machine) // Biscuit 제공
print(purchase.name) // Biscuit
purchase = PurchasedSnack(name: "Ice Cream", vendingMachine: machine)
print(purchase.name) // IceCream
print("---")
for (person, favoriteSnack) in favoriteSnacks {
print(person, favoriteSnack)
try buyFavoriteSnack(person: person, vendingMachine: machine)
}
//bom Chocolate
//ERROR: Chocolate is not vaild
//soul Chips
//Chips 제공
//model Biscuit
//ERROR: Coins is not enough. Please insert 4coin more.
'programming > Swift' 카테고리의 다른 글
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 클로저 축약
- identity Token
- SWIFT
- 자동클로저
- authorizationCode
- unowned
- 디자인패턴
- 강한참조순환
- escaping closrue
- object
- ASAuthorizationAppleIDCredential
- 강한 참조 순환
- Entity
- context
- 캡쳐리스트
- 회원가입
- CoreData
- 클로저 강한 참조
- autoclosure
- Core Data Stack
- Delegate 패턴
- weak
- core data
- 메모리 안정성
- Persistent Container
- inout 파라미터 메모리 충돌
- 클로저
- ios
- 클로저표현
- 토큰저장
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함