Swift 오류 처리 및 디버그 상세 정보
1. 표시 및 오류 던지기
Swift에서 오류는
Error
프로토콜 유형의 값으로 표시됩니다.이 빈 프로토콜은 오류 처리에 사용할 수 있는 형식을 표시합니다.Swift 매거는 관련 오류 조건을 모델링하는 데 특히 적합하며, 관련 값에 오류 성질의 추가 정보를 추가할 수 있습니다.enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeeded: Int)
case outOfStock
}
키워드
throw
를 사용하여 실행 중인 문장에서 잘못된 정보를 표시합니다.throw VendingMachineError.insufficientFunds(coinsNeeded: 5)
2. 오류 처리
(1).던지기 함수로 오류 전파
throws
를 사용하여 함수, 방법, 또는 구조기가 오류를 던질 수 있음을 나타낸다.throws
를 추가하고 화살표 -> 이전으로 되돌려줍니다.func canThrowErrors() throws -> String
:
함수를 던져야만 오류를 전파할 수 있다.throwing 함수가 아닌 오류는 함수 내부에서 처리해야 합니다.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),
"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)")
}
}
vend(itemNamed:
방법 내부에서 오류를 처리하지 않고 던진 오류를 직접 전파한다.이 방법을 호출하는 다른 코드는 do-catch
문장, try?
, try!
, 또는 오류를 계속 전파하는 방식으로 처리해야 한다.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)
}
buyFavoriteSnack(person: vendingMachine:)
도 던지기 함수로서 내부에서 호출된 vend(itemNamed:
방법은 오류를 낼 수 있기 때문에 방법 실행 앞에 키워드 try
를 추가하여 호출합니다.함수를 던지는 것과 같이 구조기를 던지는 것도 같은 방식으로 오류를 전파할 수 있다.
struct PurchasedSnack {
let name: String
init(name: String, vendingMachine: VendingMachine) throws {
try vendingMachine.vend(itemNamed: name)
self.name = name
}
}
(2).
Do-Catch
처리 오류를 사용하여 코드 블록을 실행하여do-catch 문장으로 오류를 처리할 수 있습니다.do 패키지의 코드가 오류를 내면catch 패키지와 일치하여 오류를 처리할 수 있는지 확인합니다.do {
try expression
statements
} catch pattern 1 {
statements
} catch pattern 2 where condition {
statements
} catch {
statements
}
패키지를 닫으면 어떤 오류를 처리할 수 있는지를 표시하기 위해catch 다음에 처리할 오류 모드를 작성할 수 있습니다.만약catch 패키지가 일치하는 오류 모드가 없다면, 오류를 마지막catch 패키지에 맡기고 오류를 error라는 로컬 상수에 연결합니다.
var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 8
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).")
}
// Prints "Insufficient funds. Please insert an additional 2 coins."
위의 예에서
buyFavoriteSnack(person:vendingMachine:)
함수는 try
표현식에서 호출된다. 왜냐하면 그는 오류를 던질 수 있기 때문이다.오류가 발생했을 때, 즉시 상응하는catch 패키지로 돌아가서 오류를 처리합니다.오류가 없으면 do 패키지의 나머지 문장을 계속 실행합니다.이catch 패키지는 do 패키지의 코드가 던질 수 있는 모든 오류를 처리할 필요가 없습니다.catch 패키지 처리 오류가 없으면 오류가 주위 범위로 전파됩니다.그러나 전파의 오류는 주위의 어느 범위에서 처리해야 한다.비포맷 함수에서do-catch를 포함하는 패키지는 오류를 처리해야 합니다.던지기 함수에 do-catch 패키지를 포함하거나 호출자가 오류를 처리해야 합니다.오류가 처리되지 않고 최상위 범위로 전파되면 실행 중 오류가 발생합니다.
func nourish(with item: String) throws {
do {
try vendingMachine.vend(itemNamed: item)
} catch is VendingMachineError {
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)")
}
// Prints "Invalid selection, out of stock, or not enough money."
(3).오류를 선택적 값으로 변환
오류를 선택적 값으로 변환하여 오류를 처리할 수 있습니다
try?
.try?
표현식을 실행할 때 오류가 발생하면 표현식의 값은nil입니다.func someThrowingFunction() throws -> Int {
// ...
}
let x = try? someThrowingFunction()
let y: Int?
do {
y = try someThrowingFunction()
} catch {
y = nil
}
모든 오류를 같은 방식으로 처리하고 싶을 때,
try?
를 사용하면 간결한 오류 처리 코드를 쓸 수 있습니다.다음 예에서 보듯이 모든 방법이 실패하면 nil로 돌아갑니다.func fetchData() -> Data? {
if let data = try? fetchDataFromDisk() { return data }
if let data = try? fetchDataFromServer() { return data }
return nil
}
(4).오류 전파를 사용하지 않습니다. 때때로 함수나 방법이 실행될 때 오류를 던지지 않는다는 것을 알고 있습니다.이 경우 표현식 앞에
try!
을 추가하여 오류의 전파를 금지하고 호출 포장을 실행할 때 오류가 발생하지 않는다고 단언할 수 있습니다.실제 오류가 발생하면 실행 중 오류가 발생합니다.let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")
3. 정리 작업 지정
func processFile(filename: String) throws {
if exists(filename) {
let file = open(filename)
defer {
close(file)
}
while let line = try file.readline() {
// Work with the file.
}
// close(file) is called here, at the end of the scope.
}
}
4. 단언과 선결 조건
(1).단언 디버깅을 사용하여 Swift 표준 라이브러리에서
assert(_:_:file:line:)
함수를 호출하여 단언을 작성합니다.이 함수에 전달된 표현식은 true
또는 false
입니다.조건의 결과가 false
이면 메시지가 표시됩니다.예:let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// This assertion fails because -3 is not >= 0.
단언 메시지를 생략할 수 있습니다. 예를 들면:
assert(age >= 0)
코드가 조건을 검사했다면 assertionFailure (_:file:line:) 함수를 사용하여 단언이 실패했음을 표시합니다.예:
if age > 10 {
print("You can ride the roller-coaster or the ferris wheel.")
} else if age > 0 {
print("You can ride the ferris wheel.")
} else {
assertionFailure("A person's age can't be less than zero.")
}
(2).실행 선결 조건은 조건이 가짜일 수 있지만 코드를 계속 실행할 수 있도록 조건이 진실이어야 하며 선결 조건을 사용한다.
precondition(_:_:file:line:)
함수를 호출하여 선결 조건을 작성할 수 있습니다.이 함수에 계산 결과가 진짜인지 가짜인지 표현식을 전달하고 조건 결과가 가짜일 때 메시지를 표시합니다.예:// In the implementation of a subscript...
precondition(index > 0, "Index must be greater than zero.")
실패가 발생했을 때
preconditionFailure(_:file:line:)
함수를 호출할 수도 있습니다. 예를 들어 스위치의 기본 상황을 선택했지만 모든 유효한 입력 데이터는 스위치의 한 가지 상황에 의해 처리되어야 합니다.5. 치명적인 오류
//message:
//file: “message”
//line: “message”
public func fatalError(_ message: @autoclosure () -> String = default, file: StaticString = #file, line: UInt = #line) -> Never
6. 기타 테마 모듈
Swift 4.2 기본 주제 상세 정보
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.