클로저
-클로저는 이름없는 함수로 코드블럭을 지칭한다.
-클로저는 상수나 변수의 참조를 캡처해 저장할 수 있다.
-클로저를 사용하는 이유는 기능을 저장하기 위해서 사용한다.
-클로저는 비동기 처리가 필요할 때 사용할 수 있는 코드블럭이다.
* 비동기처리란 ? = 특정 로직의 실행이 끝날때까지 기다려주지 않고 나머지 코드를 먼저 실행하는것을 비동기 처리라고 한다.
-클로저는 함수와 마찬가지로 참조타입이다.
- 예시 코드
```swift
{ (parameters) -> return type in
// 구현 코드
}
// 함수와 클로저 비교
func pay(user: String, amount: Int) {
// code
}
let payment = { (user: String, amount: Int) in
// code
}
```
```swift
// return 값 없는 클로저
let driving = { (place: String) in // place는 매개변수
print("\(place)으로 향하는 중입니다.")
}
driving("사무실")
// 출력값: 사무실으로 향하는 중입니다.
// return 값 있는 클로저
let payment = { (user: String) -> Bool in
print("\(user)님이 계산하셨습니다.")
return true
}
payment("부장님")
// 출력값: 부장님이 계산하셨습니다.
```
이스케이핑 클로저 (escaping closure)
-이스케이핑 클로저는 클로저가 메서드의 인자로 전달 되었을 때, 메서드의 실행이 종료된 후 실행되는 클로저입니다.
- 이경우 파라미터 타입 앞에 @escaping이라는 키워드를 명시해야합니다.
* 예를들어 비동기로 실행되거나 completionhandler로 사용되는 클로저의 경우!
- 클로저를 메서드의 파라미터로 넣을 수 있습니다.
참고 자료
- https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/
Documentation
docs.swift.org
예외 처리
- 실패 가능한 상황과 예외처리
* 에러처리
- 프로그램에서 에러가 발생한 상황에 대응하고 이에 대응하는 과정입니다.
-Swift에서는 런타임 에러가 발생한 경우, 이를 처리를 지원하는 클래스를 제공합니다.
-프로그램에서 모든 기능이 개발자가 예상하고 원하는대로 동작한다는 보장이 없기 때문에 예외처리를 통해 예외 상황을 구별하고 프로그램 자체적으로 오류를 해결하거나, 사용자에게 어떤 에러가 발생했는지 알려주는 등에 대한 조치와 대응을 해야합니다.
*Error
- Error는 던져질 수 있는 오류 값을 나타내는 유형을 말합니다.
- Error 프로토콜을 채택하여 사용자 정의 에러를 정의하여 사용할 수 있다
참고자료
-https://developer.apple.com/documentation/swift/error
Error | Apple Developer Documentation
A type representing an error value that can be thrown.
developer.apple.com
throw와 do-catch문 try문
* throw와 throw
-throw는 리턴 값을 반환하기 전에 오류가 발생하면 에러 객체를 반환한다는 의미이다.
-throw는 오류가 발생할 가능성이 있는 메소드 제목 옆에 써줍니다.
-throw는 오류가 발생할 구간에 써줍니다.
//예시!!!
// 표현
func canThrowErrors() throws -> String
func cannotThrowErrors() -> String
// 예시
struct Item {
var price: Int
var count: Int
}
enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeeded: Int)
case outOfStock
}
let favoriteSnacks = [
"Alice": "Chips",
"Bob": "Licorice",
"Eve": "Pretzels",
]
func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
let snackName = favoriteSnacks[person] ?? "Candy Bar"
try vendingMachine.vend(itemNamed: snackName)
}
class VendingMachine {
var inventory = [
"Candy Bar": Item(price: 12, count: 7),
"Chips": Item(price: 10, count: 4),
"Pretzels": Item(price: 7, count: 11)
]
var coinsDeposited = 0
func vend(itemNamed name: String) throws { // 👀
guard let item = inventory[name] else {
throw VendingMachineError.invalidSelection
}
guard item.count > 0 else {
throw VendingMachineError.outOfStock // 👀
}
guard item.price <= coinsDeposited else {
throw VendingMachineError.insufficientFunds(coinsNeeded: item.price - coinsDeposited) // 👀
}
coinsDeposited -= item.price
var newItem = item
newItem.count -= 1
inventory[name] = newItem
print("Dispensing \(name)")
}
}
var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 8
do {
try buyFavoriteSnack(person: "앨리스", vendingMachine: vendingMachine) // 👀
print("성공! 냠.")
} catch VendingMachineError.invalidSelection {
print("선택 불가한 항목입니다")
} catch VendingMachineError.outOfStock {
print("재고가 없습니다.")
} catch VendingMachineError.insufficientFunds(let coinsNeeded) {
print("금액이 부족합니다.. \(coinsNeeded) 코인을 추가로 넣어주세요.")
} catch {
print("앗 예상치 못한 에러가 발생했습니다! 에러 메시지: \(error).")
}
// 출력값: 금액이 부족합니다... 4 코인을 추가로 넣어주세요.
func nourish(with item: String) throws {
do {
try vendingMachine.vend(itemNamed: item)
} catch is VendingMachineError {
print("자판기에서 구매할 수 없습니다.")
}
}
do {
try nourish(with: "소고기맛 과자")
} catch {
print("예상치 못한 자판기와 관련없는 에러가 발생했습니다. 에러 메시지: \(error)")
}
// 출력값: 자판기에서 구매할 수 없습니다.
// catch에서 여러 에러 케이스를 한꺼번에 처리할 수 있습니다.
func eat(item: String) throws {
do {
try vendingMachine.vend(itemNamed: item)
} catch VendingMachineError.invalidSelection, VendingMachineError.insufficientFunds, VendingMachineError.outOfStock {
print("유효하지 않는 선택지이거나 재고가 없거나 금액이 부족합니다.")
}
}
try? 와 try!
* try?
-do-catch 구문없이도 사용 가능하다.
-에러 발생시 nil값을 반환한다.
-에러가 발생하지 않으면 리턴 값의 타입은 옵셔널로 반환된다.
* try!
- 에러가 발생을 하면 앱이 강제 종료된다.
- 반환 타입은 옵셔널 언래핑된 값이 리턴된다.
- 오류가 발생하지 않는다는 보장아래 사용하여야한다.
'Today I Learned' 카테고리의 다른 글
23년 7월 25일 TIL (0) | 2023.07.25 |
---|---|
23년 7월 24일 TIL (0) | 2023.07.24 |
23년 7월 20일 TIL (0) | 2023.07.20 |
23년 7월 19일 TIL (0) | 2023.07.19 |
23년 7월 18일 TIL (0) | 2023.07.19 |