나의 플랫폼/iOS

[iOS] Swift defer 블록

GsBOB 2017. 9. 14. 15:13

defer 블록 : 메소드 에서 코드의 흐름과 상관 없이 가장 마지막에 실행되는 블록



SQLite3를 사용할 때 참고 하면 좋을 듯 하다.


func dbExecute(dbPath: String) {

        // 1

        var db: OpaquePointer? = nil

        guard sqlite3_open(dbPath, &db) == SQLITE_OK else {

            print("Database Connect Fail")

            return

        }

        

  // 2

        defer {

            print("Close Database Connection")

            sqlite3_close(db)

        }


        // 3

        var stmt: OpaquePointer? = nil

        let sql = "create table if not exists sequence (num integer)"

        guard sqlite3_prepare(db, sql, -1, &stmt, nil) == SQLITE_OK else {

            print("Prepare Statement Fail")

            return

        }

        

 // 4

        defer {

            print("Finalize Statement")

            sqlite3_finalize(stmt)

        }


  // 5

        if sqlite3_step(stmt) == SQLITE_DONE {

            print("Create Table Success!")

        }

    }


꼼꼼한 재은 씨의 스위프트 실전편 - Chapter06 예제 소스


위 소스에서 defer 블록을 보시면 SQLite3를 종료 함수를 호출 하고 있습니다.

해당 위치에 왔을 때 바로 블록을 실행 하는게 아니라

sqlite3_step 부분까지 실행 되고 나서,

dbExecute 함수를 벗어 날때 defer블록 부분이 호출 되는 것 이다.


즉, 주석으로 표시한 숫자 순서로 말을 하면,


1 -> 3 -> 5 -> 4 -> 2 


이다.


하지만 만약 3번 위치에서 return을 할 경우는


1 -> 3 -> 2


가 되는 것이다.


그리고! 눈치 채신 분이 있겠지만 defer블록은 나중에 호출된 블록 부터 호출이 된다.

그래서 2번 위치부터 호출하지 않고 4번 위치부터 호출을 한다.



## defer 블록 특징

1. 함수 종료 직전에 실행

2. defer 블록이 읽히기 전에 종료 되면 실행 되지 않음.

3. 가장 마지막에 호출된 defer 블록 부터 역순으로 호출 된다.

4. defer블록을 중첩으로 사용할 때, 바깥쪽 블록 부터 호출 된다.



참고하세요.