defer 블록은 함수나 메소드에서 코드의 흐름과 상관없이 가장 마지막에 실행되는 블록입니다. 지연블록이라고 부르기도 하는데, 이 블록에 작성된 구문은 항상 함수의 종료 직전에 실행되기 때문에 종료 시점에 맞추어 처리해야 할 구문이 있다면 우리는 어디에 작성해야 할지 고민하지 않고 defer 블록에 넣어두기만 하면 됩니다.
특징
- defer 블록은 작성된 위치와 순서에 상관없이 함수가 종료되기 직전에 실행된다.
- defer 블록을 읽기 전에 함수의 실행이 종료될 경우 defer 블록은 실행되지 않는다.
- 하나의 함수나 메소드 내에서 defer 블록을 여러 번 사용할 수 있다. 이때에는 가장 마지막에 작성된 defer 블록부터 역순으로 실행된다.
- defer 블록을 중첩해서 사용할 수 있다. 이때에는 바깥쪽 defer 블록부터 실행되며 가장 안쪽에 있는 defer 블록은 가장 마지막에 실행된다.
아래와 같이 코드 예시가 있다고 가정하고, 결과가 어떻게 나오는지 확인해보도록 하겠습니다.
func numberFunc(num: Int) {
print(" 1 ")
guard num > 1 else {
print(" num < 1 ")
return
}
defer {
print("first defer")
}
print(" 2 ")
var num2: Int = 900 + num
guard num2 > 999 else {
print(" num2 < 999 ")
return
}
defer {
print("second defer")
print(num2)
}
print(" 3 ")
}
1. 변수 num이 0인 경우
이 경우는 첫 번째 guard 조건에서 걸리는 경우입니다.
결과는 1과 num < 1 이 출력되었습니다. 첫번째 defer 구문은 실행되지 않습니다.
2. 변수 num이 2인 경우
이 경우는 두 번째 guard 조건에서 걸리는 경우입니다. num의 값이 2로 첫 번째 guard 구문은 통과되었지만 num2의 값이 902가 되어 999보다 크다는 조건을 충족하지 못해 두 번째 guard 에서 걸리게 됩니다.
어떻게 출력되었는지 보시죠. 첫 프린트인 1이 출력되고, 두 번째 프린트인 2까지 출력되었습니다. 다음으로 두 번째 guard 구문에 있는 프린트가 출력되었습니다. 마지막으로 첫 번째 defer 구문이 출력되었습니다.
3. 변수 num이 100인 경우
이번 경우는 모든 guard 구문이 통과된 다음 실행되는 경우입니다.
첫 번째, 두 번째, 세 번째 프린트가 차례대로 출력되고 defer 구문이 역으로 출력되는 모습입니다. defer 구문에서는 순서대로 출력됩니다.
그럼 defer 구문 안에 defer 구문이 있으면 어떻게 출력이 될까요? 두 번째 defer 구문을 변경해보도록 하겠습니다.
defer {
print("second defer")
defer {
print("추가된 defer 구문입니다.")
}
print(num2)
}
이제 다시 num 값을 100으로 두고 출력해보겠습니다.
1, 2, 3 을 차례로 출력하고 두 번째 defer 구문을 출력한 뒤 두 번째 defer 구문 안에 있는 중첩된 구문을 출력합니다.
defer 블록은 정확하게 return 되기 직전에 실행됩니다. 실제로 이 블록은 함수에서 사용된 각종 리소스의 처리나 해제, 연결 종료 등의 구문을 처리하는 용도로 유용하게 사용됩니다.
'Mobile > iOS' 카테고리의 다른 글
[iOS] UIKit 미리보기 기능 추가(Preview) (0) | 2023.04.01 |
---|---|
[iOS] 커스텀 뷰 만들기(@IBDesignable & @IBInspectable) (0) | 2023.03.31 |
[iOS] 접근 제한자 간단 정리 (0) | 2023.01.11 |
[iOS] Xcode 14, iOS 15 에서 Navigation Bar Color 설정 방법 (0) | 2023.01.11 |
[iOS] 강한 참조와 약한 참조 (0) | 2023.01.03 |