ํ๋ก๊ทธ๋จ ์คํ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ๊ทธ ์ํฉ์ ๋ํ ์ ์ ํ ์ฒ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค.
์ด ๊ณผ์ ์ ์๋ฌ ์ฒ๋ฆฌ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
Swift์์๋ ๋ฐํ์ ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ๊ทธ๊ฒ์ ์ฒ๋ฆฌ๋ฅผ ์ํด ์๋ฌ์ ๋ฐ์(Throwing), ๊ฐ์ง(Cactching), ์ฆ์(Propagating), ์กฐ์(manipulating)
์ ์ง์ํ๋ ์ผ๊ธ ๊ฐ์ฒด๋ฅผ ์ ๊ณตํฉ๋๋ค.
Swift์์ ์๋ฌ ์ฒ๋ฆฌ๋ Cocoa์ NSError ํด๋์ค์ ์ํธ ํธํ๋๋ Error Handling Pattern์ ์ฌ์ฉํฉ๋๋ค.
์๋ฌ์ ํ์์ ๋ฐ์
Swift์์ ์๋ฌ๋ Error ํ๋กํ ์ฝ์ ๋ฐ๋ฅด๋ ํ์
์ ๊ฐ์ผ๋ก ํํ๋ฉ๋๋ค.
์ด ์ค์์ ์ด๊ฑฐํ์ ์ด๋ฐ ๊ด๋ จ๋ ์๋ฌ๋ฅผ ๊ทธ๋ฃนํ(Grouping)ํ๊ณ ์ถ๊ฐ์ ์ธ ์ ๋ณด๋ฅผ ์ ๊ณตํ๊ธฐ์ ์ ํฉํฉ๋๋ค.
enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeeded: Int)
case outOfStock
}
throw VendingMachineError.insufficientFunds(coinsNeeded: 5) // Error๋ฅผ ๋ฐ์์ํค๋ Throw ๊ตฌ๋ฌธ
์๋ฌ ์ฒ๋ฆฌ
Swift์์๋ 4๊ฐ์ง ์๋ฌ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
*1. Error๋ฅผ Returnํ์ฌ ํธ์ถํ ํจ์๋ก๋ถํฐ ์ฒ๋ฆฌํ๊ฒ ํ๋ ๋ฐฉ๋ฒ *
*2. do catch ๊ตฌ๋ฌธ *
*3. ์ต์
๋ ๊ฐ์ ๋ฐํํ๋ ๋ฐฉ๋ฒ *
*4. assert๋ฅผ ์ฌ์ฉํด ๊ฐ์ ํฌ๋์ฌ๋ฅผ ๋ฐ์ *
์๋ฌ ๋ฐ์ ํจ์ ์ฌ์ฉํ๊ธฐ
์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ค๋ ํจ์๋ฅผ throwing function์ด๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
'->' ํค์๋ ์ ์ throws ํค์๋๋ฅผ ์ ์ต๋๋ค.
func canThrowErrors() throws -> String
func cannotThrowErrors() -> String
์ค์ง throwing function๋ง์ด ์๋ฌ๋ฅผ ๋ฐ์์ํฌ ์ ์์ต๋๋ค. ๋ง์ฝ throwing function์ด ์๋ ํจ์์์ throw๊ฐ ๋ฐ์ํ๋ค๋ฉด ๋ฐ๋์ ๊ทธ ํจ์๋ด์์ throw์ ๋ํด ์ฒ๋ฆฌ๋ผ์ผ ํฉ๋๋ค. throw ์๋ฌ๋ฅผ ๋ฐ์์ํค๋ฉด ํจ์๋ฅผ ํ์ถํฉ๋๋ค.(early exit)
thorwing function์ ํธ์ถํ๋ ๋ฉ์๋๋ ๋ฐ๋์ do-catch, try?, try!
๊ตฌ๋ฌธ์ ์ฌ์ฉํด ์๋ฌ๋ฅผ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
Do-Catch๋ก ์๋ฌ ์ฒ๋ฆฌํ๊ธฐ
do {
try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
print("Success! Yum.")
} catch VendingMachineError.invalidSelection {
print("Invalid Selection.")
} catch VendingMachineError.outOfStock {
print("Out of Stock.")
} catch VendingMachineError.insufficientFunds(let coinsNeeded) {
print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.")
} catch {
print("Unexpected error: \(error).")
}
buyFavoriteSnack()๋ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ throw function์
๋๋ค.
์ฌ๊ธฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด, catch ๊ตฌ๋ฌธ์ ์ ๋ฌํด ์ ์ ํ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ๋ง์ฝ ๋ฐ์ํ ์ข
๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ catch ๊ตฌ๋ฌธ์ด ์๋ค๋ฉด ๋ง์ง๋ง catch ๊ตฌ๋ฌธ์์ ๊ฑธ๋ฆฌ๊ฒ ๋ ๊ฒ ์
๋๋ค.
๋ค๋ฅธ ์์ ๋ก๋ ๋ค์๊ณผ ๊ฐ์ด ์ฒ๋ฆฌํ ์๋ ์์ต๋๋ค.
func nourish(with item: String) throws {
do {
try vendingMachine.vend(itemNamed: item)
} catch is VendingMachineError { // ๋ชจ๋ VendingMachineError ๊ตฌ๋ถ์ ์ํด is๋ฅผ ์ฌ์ฉ
print("Invalid selection, out of stock, or not enough money.")
}
}
do {
try nourish(with: "Beet-Flavored Chips")
} catch {
print("Unexpected non-vending-machine-related error: \(error)")
// ์ฌ๊ธฐ์์ ์ฒ๋ผ catch๋ฅผ ๊ทธ๋ฅ if-else์์ else ๊ฐ์ด ์ฌ์ฉ ๊ฐ๋ฅ
}
// Prints "Invalid selection, out of stock, or not enough money."
์๋ฌ๋ฅผ ์ต์ ๋ ๊ฐ์ผ๋ก ๋ณํํ๊ธฐ
func someThrowingFunction() throws -> Int {
// ...
}
let x = try? someThrowingFunction()
let y: Int?
do {
y = try someThrowingFunction()
} catch {
y = nil
}
์๋ฌ๊ฐ ๋ฐ์ํ๋ค๋ฉด x, y๋ nil ์ด ๋ฉ๋๋ค. ๊ทธ๋ ์ง ์๋ค๋ฉด ๋ฆฌํด ๊ฐ์ ๊ฐ์ต๋๋ค. ์ฆ x, y๋ ์ต์ ๋ Int ์๋ฃํ์ ๊ฐ์ต๋๋ค.
์๋ฌ ๋ฐ์์ ์ค์งํ๊ธฐ
์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์ ๊ฒ์ด๋ผ๊ณ ํ์ ํ๋ ๊ฒฝ์ฐ try!
๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํน์ runtime assertion์ ์ฌ์ฉํด ์๋ฌ๋ฅผ ๋ฐ์์ํฌ ์ ์์ต๋๋ค.
defer ๊ตฌ๋ฌธ
์ ๋ฆฌ ์ก์ ๊ธฐ์ => defer ๊ตฌ๋ฌธ์ ์ฌ์ฉํด ํจ์๊ฐ ์ข ๋ฃ ๋ ํ ํ์ผ ์คํธ๋ฆผ์ ๋ซ๊ฑฐ๋, ์ฌ์ฉํ ์์์ ํด์ง ํ๋ ๋์ ์ผ์ ํ ์ ์์ต๋๋ค.
func processFile(filename: String) throws {
if exists(filename) {
let file = open(filename)
defer {
close(file) // block์ด ๋๋๊ธฐ ์ง์ ์ ์คํ, ์ฃผ๋ก ์์ ํด์ ๋ ์ ์ง์ ์ฌ์ฉ
}
while let line = try file.readline() {
// Work with the file.
}
// close(file) is called here, at the end of the scope.
}
}
'iOS ๐ฅ > Swift' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Swift์์ Abstract Class ๋ง๋ค๊ธฐ (0) | 2023.06.06 |
---|---|
Swift ํด๋์ค ์์๊ณผ ์ด๊ธฐํ (0) | 2021.06.25 |
Codable Protocol์ ์ด์ฉํด์ ๋ณต์กํ JSON Parsing ํ๊ธฐ (0) | 2021.04.15 |
Swift Date์ String ๊ฐ์ ๋ณํ (0) | 2021.04.07 |
Swift Enum๊ณผ Optional (0) | 2021.02.09 |