iOS/Swift 상식

defer

HJ39 2023. 3. 9. 01:30

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는 실행된다.)

 

 

# 참고한 사이트

  1. https://swieeft.github.io/2020/02/26/defer.html
  2. https://boidevelop.tistory.com/47

'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