[Swift] defer 구문: 후처리

minsson·2022년 11월 10일
7
post-thumbnail

제가 나중에 보기 위해 정리해놓은 자료이므로 틀린 내용이 있을 수 있습니다. 댓글로 피드백 주시면 바로 수정하겠습니다. 감사합니다. ☺️ - 민쏜 -


개념

  • defer 구문을 쓰면, 그 내부의 코드들이 나중에 실행되게 만들 수 있다.
    • 그 나중은, defer 구문을 감싸고 있는 가장 가까운 코드 블록을 벗어나는 시점이다.
    • 코드를 읽어내려가면서 defer 구문을 훑기만 했다면 어떤 이유로 defer 구문의 최대 근접 코드 블록을 벗어나든 실행된다.
      • return 등을 만나 정상적으로 빠져나가도, 오류가 발생해서 빠져나가도 상관없다.

왜 쓸까

  • 공식문서에 따르자면, defer 구문은 defer 구문이 나타나는 범위 외부로 프로그램 제어를 전송하기 직전에(just before transferring program control outside of the scope) 코드를 실행하는 데 사용된다.
    • 쉽게 말해, 현재 코드 블록을 나가기 전 꼭 실행해야 하는 코드를 실행시키기 위해서다.

사용 예시

  • defer 구문은 오류처리를 할 때 유용하게 쓰인다.

  • 물론, defer 구문은 함수, 메서드, 반복문, 조건문 등 보통의 코드 블록 어디서든 사용할 수 있다.

  • 함수 내에서 파일을 열어 사용하다가 오류가 발생해 코드가 블록을 빠져나가든, return을 만나서 나가든, 열어놓은 파일을 정상적으로 닫아주지 않으면 메모리에 남아있을 수 있다.

    • defer 구문이 없었다면:
    func writeData() {
        let file = openFile()
    
        if ... {
            close(file) // 실수로 누락시키면 안되니 조마조마..
            return
        }
    
        if ... {
            close(file) // 같은 코드를 중복해서 쓰는 문제까지..
            return
        }
    }
    • defer 구문이 있으니까:
    func writeData() {
        let file = openFile()
    
        // defer를 훑고 지나가기만 했다면,
        // 최대 근접 구문인 writeData() 메서드의 코드블록이 끝날 때 무조건 실행
        defer { 
            close(file)
        }
    
        if ... {
            return // 안심하고 리턴
        }
    
        if ... {
            return // 안심하고 리턴
        }
    }

주의사항

  • defer 구문 내부에는 break, return 등과 같이 구문을 빠져나갈 수 있는 코드 또는 오류를 던지는 코드를 작성하면 안된다.

    breakreturn
  • 여러 개의 defer 구문이 하나의 범위(블록) 내부에 속한다면, defer 구문을 훑고 지나갈 때마다 스택처럼 쌓여, 쌓인 순서의 역순으로 실행된다.

    • 이거 관련해서 구현 코드를 보고 싶었는데, Xcode에서 option 키 누르고 클릭해도, Jump To Definition을 눌러도 반응이 없다. 왜일까...?

참고자료

나중에 보면 좋을 것 같은 자료

[Swift] defer의 동작 원리는 무엇일까? (번역)
(원문을 쓴 원저자도, 번역하신 분도 경이롭다...! 😵)

profile
풋사과 iOS 개발자

2개의 댓글

comment-user-thumbnail
2022년 11월 11일

좋은 내용 잘 보고 갑니다 👍

1개의 답글