옵셔널은 함수의 성공/실패를 값의 존재/부재로 알 수 있지만, 에러 핸들링은 실패의 근본적인 이유를 알려주고 이 에러를 프로그램의 다른 부분으로 넘겨주기도 함.
함수가 에러가 발생했을때는, throw한다고 한다. 에러를 던지는거임.
그러면 이 함수의 caller(함수를 호출한 함수)가 에러를 catch해서 반응을 해준다.
func canThrowError() throws { ... }
//에러를 뱉을수도 있고 안뱉을수도 있는 함수
이 함수를 호출할 때는, try 키워드를 앞에 붙여줘야 한다.(prepend the try keyword to the expression)
do{
try canThrowError()
//에러 발생안함
}
catch{
//에러 발생함
}
에러가 발생했다면 catch절에서 에러를 핸들링해줌.
뱉는 오류에 따라서 다수의 catch가 있을 수 있음.
아래는 예시!
func makeASandwich() throws {
// ...
}
do {
try makeASandwich()
eatASandwich()
} catch SandwichError.outOfCleanDishes {
washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
buyGroceries(ingredients)
}
makeASandwich는 에러를 여러 개 뱉어낼 수 있는데,
만약 에러가 발생하지 않았다면 곧바로 eatASandwich를 실행하면 되는거고,
makeASandwich 에러가 뱉어낼 수 있는 에러를 모아둔 SandwichError에서 outOfCleanDishes 에러가 발생하면 washDishes가 처리해 주는거고,
missingIngredients의 경우에는 함수형식으로 에러가 발생할 수도 있다~는 것이다.
말만 보면 좀 어렵다.
두 개를 거의 묶어서 부르는 듯 한데, 프로그램 실행 중에 무조건 참이여야 프로그램이 제대로 동작하는 거임.
사전 가정과 전제 조건이라고 직역되는데, 말 그대로 프로그램이 실행되면서 이 조건들이 참이면 평소대로 실행되고, 거짓이라면 프로그램이 종료되고, 코드 실행이 중단되고, 앱이 종료돼 버린다.
코딩 하는중에 내가 원하는 예상결과를 나타내므로, 코드에 요놈들이 포함될 수 있다.
Assertion은 개발 중 실수와 부정확한 가정을 발견하는 데 도움을 줄 수 있고, Precondition은 production(실제 서비스를 위한 운영 환경)의 문제를 찾아낼 수 있음.
게다가 이건 에러와 다르게, 예상 가능하거나 해결할 수 있는 에러를 찾아내는 데 사용되는 게 아니라, failed assertion & precondition은 invalid한 프로그램 상태를 나타내기 때문에 failed assertion을 catch할 방법이 없다.
이놈들은 프로그래밍 간에 꼭 필요한 건 아니지만, 사용하면 예상하지 못한 프로그램 종료를 좀 더 예측할 수 있고, 피해를 최소화할 수 있다는 장점이 있다.
디버깅도 쉬워짐.
Assertion과 Precondition의 차이는 이것들이 언제 체크되는지에 따라 구분되는데, Assertion은 디버그 빌드 시에만 체크되지만 Precondition은 디버그 빌드와 production 빌드 시에 체크된다.
즉 Assertion은 development process에서는 실행 퍼포먼스에 영향을 주지 않으므로 원하는 만큼 쓸 수 있다는 것!
assert(\_ : _ : file : line : )
위 함수의 사용으로 Assertion을 사용할 수 있다.
let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// Assertion이 실패함. age가 0 이상이여야 하는디..
메시지를 생략하고 조건만 넣을수도 있음.
assert(age>=0)
조건을 미리 체크할 때는 assertionFailure로 원하는 동작을 실행시킬 수 있음.
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.")
}
assertionFailure로 따로 조건을 걸지 않고 기존의 조건을 사용하면서 원하는 Assertion을 걸 수도 있다!!
false가 될 가능성이 있는 조건이 있지만, 프로그램 실행 시 반드시 참이여야 하는 조건이 있을 때 Precondition을 설정하면 된다.
precondition(_:_:file:line:)
이걸 사용하는데,
// In the implementation of a subscript...
precondition(index > 0, "Index must be greater than zero.")
이런식으로 쓰면 된다.
Assertion과 유사하게
preconditionFailure(_:file:line:)
도 사용 가능함!