defer는 되게 신기하게 동작하는 기능이다.
특징
현재 코드 블록을 빠져나가기 전에 실행해야 하는 코드를 작성할 수 있다.
함수에서 오류가 발생하여 코드가 블록을 빠져가게 되면 해당 함수가 할당한 메모리를 안전하게 해제할 수 있다.
실행되는 순서는 다음 두 가지 규칙을 따른다.
실행 규칙
- defer가 중복될 때 역순으로 실행된다.
- 하나의 defer는 선언된 코드 블록을 빠져나가기 직전에 실행된다.
예시를 통해 알아보면 빠르게 이해할 수 있다.
class A{
func test() {
defer {
print("test 1")
}
do {
defer {
print("test 2")
}
print("test 3")
}
for i in 0..<2 {
defer {
print("test 4")
}
if i % 2 != 0 {
defer {
print("test 5")
}
print("test 6")
}
}
defer {
print("test 7")
}
print("test 8")
}
}
/*
실행 결과
test 3
test 2
test 4
test 6
test 5
test 4
test 8
test 7
test 1
*/
하나씩 분리해서 보면
test() 내부에는 크게 5개 코드 블록이 존재한다.
defer print("test 1") , do 구문, for 반복문, defer print("test 7") 구문, print("test 8")
defer의 규칙 때문에 "test 1", "test 7"은 가장 나중에 실행된다.
첫 번째로 do 구문이 실행되는데
do 구문 내부
do {
defer {
print("test 2")
}
print("test 3")
}
defer은 속해 있는 코드블록이 종료되기 직전에 실행되므로 "test 3"가 먼저 출력되고 do 구문을 빠져나가기 전에 "test 2"가 실행된다.
두 번째로 for 반복문이 실행된다.
for i in 0..<2 {
defer {
print("test 4")
}
if i % 2 != 0 {
defer {
print("test 5")
}
print("test 6")
}
}
i는 0, 1 두 반복되어 실행된다.
i = 0인 경우
if 문 조건이 성립하지 않으므로 if 내부는 실행되지 않는다.
하지만 defer "test 4"는 i = 0 일 때 코드 블록이 종료되므로 실행된다.
i = 1인 경우
if 문 조건이 성립되어 실행된다.
if 문 내부에서 defer 실행 규칙에 의해
"test 6"가 출력되고 "test 5"가 출력된다.
그 후 if문 코드 블록을 빠져나온 뒤 "test 4"가 출력된다.
세 번째 print("test 8")
test() 내부에서 마지막 부분의 실행 코드이므로 출력된다.
네 번째 defer print("test 7")
defer 실행 규칙에 의해 defer는 역순으로 실행된다.
따라서 defer print("test 7")이 defer print("test 1") 보다 밑 부분에 있으므로 defer print("test 7")이 먼저 실행된다.
따라서 "test 7"이 먼저 출력되고 "test 1" 이 뒤에 출력된다.
defer 가 실행되지 않는 경우
당연하게 들리겠지만
defer가 실행되기 전에 오류가 발생하여 throw 되는 경우
중간에 함수가 return 되는 경우 defer가 실행되지 않는다.
(throw 되기 전이나 return 되기 전에 있는 defer는 실행된다.)
# 참고한 사이트
'iOS > Swift 상식' 카테고리의 다른 글
Some (0) | 2023.03.25 |
---|---|
property wrapper (0) | 2023.03.10 |
Extension 이란? (0) | 2023.03.08 |
Escaping 사용하기 (0) | 2023.03.05 |
Escaping 개념 (0) | 2023.03.04 |