티스토리 뷰
Swift Docs > The Basics > Assertions and Preconditions 에 있는 내용을 토대로 한 글입니다!
# Assertions 과 preconditions 용도
Assertions 와 preconditions 은 런타임에 체크됩니다.
futher code 를 실행시키기 전에 essential condition 을 만족시켰는 지 검증하는 용도로 사용할 수 있습니다.
assertion 또는 precondition 의 조건이 true 면 코드는 계속 실행되고
false 면 현재 프로그램 상태가 invalid 하다고 판단되어서 코드 실행이 멈추고 앱이 종료됩니다.
Assertion은 개발 중에 실수나 잘못된 가정을 찾는 데 도움이 되고
preconditions는 production에서 이슈를 발견하는 데 도움이 됩니다.
Error Handling 과 달리 assertions 과 preconditions 은 복구가능한 에러 또는 예상되는 오류를 위해 사용되는 것이 아닙니다.
실패한 assertion 또는 precondition은 invalid 프로그램 상태를 나타내므로 failed assertion을 catch 할 방법이 없습니다.
assertions와 preconditions 사용은 invalid state가 발생하면 앱이 종료되므로 문제를 파악하기 더 쉽습니다.
또한 invalid state 에서 실행을 중지하는 것은 잘못된 상태로 인해 발생할 수 있는 damage를 제한하는 데도 도움이 됩니다.
# Debugging with Assertions
assert(_:_:file:line:) 에 조건과 조건의 결과가 false 일 경우 표시할 메세지를 넘길 수 있습니다.
아래 예제에서는 age가 음수라면 assertion이 실패하고 앱이 종료됩니다.
let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// This assertion fails because -3 isn't >= 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.")
}
# Enforcing Preconditions
조건 (condition) 이 false일 가능성이 있을 때마다 precondition을 사용할 수 있고 다음 코드를 실행하려면 조건은 반드시 true 여야합니다. 예를들어 subscript가 범위를 벗어나지 않았는 지, function이 valid value 를 전달받았는 지 확인할 때 쓸 수 있습니다.
precondition(_:_:file:line:) 에 조건과 조건의 결과가 false 일 경우 표시할 메세지를 넘길 수 있습니다.
// In the implementation of a subscript...
precondition(index > 0, "Index must be greater than zero.")
preconditionFailure(_:file:line:) function 을 호출해서 failure이 발생했음을 나타낼 수 도 있습니다.
# Assertions 과 preconditions 차이
assertion과 precondition의 차이는 언제 체크되냐에 있습니다.
assertion은 오직 debug build 에서만 체크됩니다.
precondition은 debug build와 production build 에서 모두 체크됩니다.
즉 production build 에서 assertion 안에 있는 condition은 평가되지 않습니다.
이는 프로덕션 성능에 영향을 주지 않으면서 개발 과정 중, 많은 assertions 을 사용할 수 있다는 것을 의미합니다.
💬💬💬
문서에는 이렇게 간단히 말하지만,,,
production build 라면 무조건 assertion 체크안하는게 아니라 빌드세팅에 따라 체크여부가 다릅니다
즉 production에서 빌드세팅을 default 로 설정되있는 것에서 -Onone으로 바꿨다,,, 이러면 해당되지 않는 것입니다.
그리고 assertFailure 은 assert 랑 조건이 좀 다른 것도 유의해야합니다.
# Preconditions Unchecked 모드
unchecked mode (-Ounchecked) 로 컴파일하면 preconditions이 체크되지 않습니다.
컴파일러는 preconditions 이 항상 true 라고 가정하고, 그에 따라 코드를 최적화합니다.
💬💬💬
assertion 과 마찬가지로 precondition과 preconditionfailure 도 조건이 좀 다르므로 유의해줘야합니다.
아래의 precondition, preconditionfailure 문서를 들어가보면 unchecked 모드는 precondition만 해당되는 것을 알 수 있습니다.
참고로 Optimization Level 에서 -Ounchekced 가 없어서 (XCode 12.5 기준)
Other을 선택하고 직접 입력해줬습니다 동작 잘하더라구요!
# fatalError
하지만 fatalError(_:file:line:) function은 위와 같은 optimization settings 에 상관없이 항상 실행을 중단합니다.
프로토타이핑 또는 초기 개발 중에 fatalError를 사용해서 아직 구현되지 않은 기능에 대한 stub 을 생성할 수 있습니다.
예를들어 stub 구현으로 fatalError("Unimplemented") 를 작성해줄 수 있겠습니다.
# 정리
문서가 너무 헷갈려서 테스트해봤습니다.
하나씩 주석을 풀어가며 앱이 종료안되는가 (즉 체크를 안하는가) 를 봤습니다.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
assert(1==2)
//assertionFailure()
//precondition(1==2)
//preconditionFailure()
}
}
1. Optimization Level 이 -Oneone 일 때 (Debug 빌드의 디폴트 값)
assertion = 체크함
assertionFailure = 체크함
precondition = 체크함
preconditionFailure = 체크함
2. Optimization Level 이 -O 일 때 (Release 빌드의 디폴트 값)
assertion = 체크안함
assertionFailure = 체크안함
precondition = 체크함
preconditionFailure = 체크함
3. Optimization Level 이 -Osize 일 때
assertion = 체크안함
assertionFailure = 체크안함
precondition = 체크함
preconditionFailure = 체크함
4. Optimization Level 이 -Ounchekced 일 때
assertion = 체크안함
assertionFailure = 체크함
precondition = 체크안함
preconditionFailure = 체크함
참고로 fatalError는 Optiomization Level 과 상관없이 항상 체크합니다.
# 첨언
위의 variation들을 다 기억할 수 있을까요...?
릴리즈 빌드에서는 실행되면 안된다!! 할 때 그냥 이렇게 하는 게 더 편하고 확실할 것 같네요
#if !RELEASE
...
#endif
'🍏 > Swift' 카테고리의 다른 글
[Swift] Substring (0) | 2021.12.12 |
---|---|
Swift, Dart, Python % Operator 비교 (0) | 2021.12.07 |
[Swift] Self Type (0) | 2021.11.22 |
[Swift Algorithms] chunks(ofCount:) (0) | 2021.09.28 |
[Swift] async / await 사용사례 (0) | 2021.07.06 |
- Total
- Today
- Yesterday
- SerializerMethodField
- flutter build mode
- Sketch 누끼
- Flutter Text Gradient
- Flutter getter setter
- 플러터 싱글톤
- flutter 앱 출시
- flutter deep link
- DRF APIException
- 구글 Geocoding API
- Django FCM
- Flutter Clipboard
- 장고 Custom Management Command
- PencilKit
- Flutter Spacer
- Flutter 로딩
- ribs
- github actions
- cocoapod
- 플러터 얼럿
- flutter dynamic link
- 장고 URL querystring
- Watch App for iOS App vs Watch App
- METAL
- drf custom error
- ipad multitasking
- Python Type Hint
- Django Firebase Cloud Messaging
- Django Heroku Scheduler
- Dart Factory
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
29 | 30 | 31 |