프로그래밍Swift 개발자

Swift에서 defer란 무엇이며, 왜 필요한가요? 사용 시 어떤 함정이 있을까요?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문에 대한 배경:

defer는 코드 블록이 끝난 후에 리소스를 보다 편리하게 관리하고 작업을 수행하기 위해 Swift에 도입되었습니다. 이는 다른 언어의 finally와 유사합니다. 이러한 구조는 리소스를 정리하거나 작업을 종료하는 단계를 명확하게 보여주는 데 도움이 됩니다.

문제:

많은 초보자들은 defer가 즉시 중첩된 코드를 실행한다고 생각하지만, 항상 트리거되는 순간을 정확히 이해하지는 못합니다. 또한 여러 defer 블록이 있을 경우 LIFO(Last In, First Out) 규칙을 모르면 이해하기 힘든 경우도 있습니다. try/catch 및 조기 종료와 관련된 어려움이 있을 수 있습니다.

해결책:

defer는 현재 함수 블록을 빠져나가기 직전에 범위 내에서 중첩된 코드를 실행합니다. 함수에서의 조기 종료(예: return, throw, break 등)가 일어나더라도 실행됩니다. 여러 defer는 등장 순서의 역순으로 실행됩니다.

코드 예:

func readFile() { print("파일 열기") defer { print("파일 닫기") } print("1번째 줄 읽기") if Bool.random() { print("조기 반환!") return } print("2번째 줄 읽기") } readFile() // 콘솔에는 항상: 파일 열기, ..., 파일 닫기 (마지막에)

주요 특징:

  • defer는 함수/메서드의 범위를 벗어날 때 항상 작동합니다.
  • 여러 defer는 스택 원칙(LIFO)으로 작동합니다.
  • 조기 return이나 오류가 발생하더라도 실행됩니다.

함정 질문들.

defer를 함수 외부에서 사용할 수 있나요?

아니요, defer는 함수, 메서드, 초기화자 및 디초기화자 내부에서만 허용됩니다. 예를 들어, 파일의 전역 영역이나 함수 외부의 코드 블록 내부에 배치할 수 없습니다.

블록 내에서 예외(throw)가 발생하면 defer는 어떻게 되나요?

defer는 그래도 실행됩니다. 이것이 그의 장점 중 하나로, 오류(throw)가 발생하더라도 리소스가 보장되게 해방됩니다. 안전한 리소스 해방 패턴이 구현됩니다.

여러 defer의 실행 순서는 어떻게 되나요?

그들은 역순으로 실행됩니다(LIFO): 나중에 선언된 defer가 먼저 실행됩니다.

코드 예:

func test() { defer { print("첫 번째") } defer { print("두 번째") } print("내부") } test() // 출력: "내부", "두 번째", "첫 번째"

일반적인 오류 및 안티 패턴

  • 자체적인 return/throw가 발생할 수 있는 코드에 defer를 사용하는 경우, 실행 순서의 혼란이 있을 수 있습니다.
  • defer를 남용하여 여러 블록으로 함수의 가독성을 떨어뜨리는 경우.
  • 함수의 범위를 넘어 defer를 사용하려고 하는 시도.

실제 사례

부정적인 케이스

여러 개의 비일관적으로 배치된 defer가 있는 함수; 일부 리소스의 해제를 잊고 함수에서 다양한 위치로 돌아갑니다. 이는 리소스 누수 및 동작 디버깅의 어려움을 초래합니다.

장점: 코드의 일관성, 정리 작업이 한 곳에 "모여" 있습니다.

단점: 무슨 일이 일어나고 어떤 순서로 실행되는지 추적하기 어렵습니다; 논리 오류로 인한 누수 가능성이 있습니다.

긍정적인 케이스

중요한 각 단계에 대한 하나의 defer가 있으며, 리소스가 초기화되는 곳에 배치되고 주석이 추가됩니다. 코드 리뷰에서 확인됩니다.

장점: 리소스의 보장된 해제, 행동 순서에 대한 명확한 이해.

단점: 새로운 리소스 및 정리 블록을 추가할 때 규율과 주의가 필요합니다.