Swift의 willSet과 didSet: 정의, 구문 및 관찰자 작동 방식

저자: IT Sectr 게시일: 2026-06-20 읽는 시간: 9 분

willSet과 didSet은 Swift의 프로퍼티 관찰자(property observers)로, 프로퍼티 값이 변경되기 전후에 코드를 실행할 수 있게 해줍니다. computed properties와 달리 관찰자는 새 값을 계산하지 않고 변경에만 반응합니다. Apple 문서 The Swift Programming Language(2026)에 따르면 관찰자는 데이터 유효성 검사, 인터페이스 동기화 및 코드 변경 로깅에 필수적입니다.

핵심 사항

  • willSet — 프로퍼티의 새 값을 저장하기 전에 호출됩니다
  • didSet — 새 값을 저장한 후에 호출됩니다
  • newValue — willSet의 암시적 매개변수로, 새 값을 포함합니다
  • oldValue — didSet의 암시적 매개변수로, 이전 값을 포함합니다
  • 관찰자 — 초기화 중 및 init 내부에서 작동하지 않습니다

Swift에서 willSet과 didSet이란?

willSet과 didSet은 Swift의 프로퍼티 관찰자(property observers)로, stored properties의 변경을 추적하는 내장 메커니즘입니다.

수동 setter 구현이나 콜백 시스템이 필요한 다른 언어와 달리, Swift는 변경에 반응하기 위한 선언적 구문을 제공합니다. 관찰자는 프로퍼티 선언 바로 뒤에 추가되며 별도로 호출할 필요가 없습니다.

Apple Developer Documentation(2026)에 따르면 property observers는 모든 클래스, 구조체 또는 열거형의 stored properties에서 지원됩니다. computed properties에서는 작동하지 않습니다. 값을 저장하지 않기 때문이며, computed properties의 경우 변경에 대한 반응이 setter에서 직접 구현됩니다.

willSet이 호출되는 시점

willSet은 프로퍼티에 새 값이 할당되기 직전에 호출됩니다. willSet 내부에서는 설정될 값을 포함하는 암시적 매개변수 newValue를 사용할 수 있습니다. 이 시점에서 프로퍼티의 현재 값은 아직 변경되지 않았으며, 프로퍼티를 통해 직접 이전 값을 읽을 수 있습니다.

Swift Evolution 제안 SE-0001(2024)에 따르면 willSet은 실제 변경 전에 유효성 검사 또는 로깅을 수행할 수 있는 기능을 제공합니다. willSet에서 예외가 발생하면 새 값이 적용되지 않아 관찰자가 데이터 보호 메커니즘이 됩니다.

didSet이 호출되는 시점

didSet은 새 값이 할당된 직후에 호출됩니다. didSet 내부에서는 변경 전의 값을 포함하는 암시적 매개변수 oldValue를 사용할 수 있습니다. 이 시점에서 프로퍼티는 이미 새 값을 포함하고 있으며, 이를 이전 값과 비교할 수 있습니다.

Swift by Sundell(2025)에 따르면 didSet은 가장 인기 있는 관찰자입니다. UI 업데이트, 종속 필드 재계산 또는 변경 후 서버로 데이터 전송과 같은 후처리에 가장 자주 필요하기 때문입니다.

프로퍼티 관찰자 구문

Property observers는 프로퍼티 바로 뒤에 중괄호를 사용하여 선언됩니다. 최소 구문은 하나의 관찰자만 필요하지만 둘 다 선언할 수 있습니다.

swift
var score: Int = 0 {
    willSet {
        print("점수가 \(newValue)(으)로 변경됩니다")
    }
    didSet {
        print("점수가 \(oldValue)에서 \(score)(으)로 변경되었습니다")
    }
}

관찰자 모두 선택 사항입니다. willSet만, didSet만, 또는 둘 다 지정할 수 있습니다. willSet의 경우 괄호 안에 이름을 지정하여 newValue의 이름을 바꿀 수 있습니다.

swift
var username: String = "guest" {
    willSet(newName) {
        print("\(newName) 설정 중")
    }
    didSet(oldName) {
        print("이전 \(oldName), 현재 \(username)")
    }
}

Swift Language Guide(2026)에 따르면 매개변수 이름을 바꾸면, 특히 긴 이름을 가진 대규모 프로젝트에서 프로퍼티와 관찰자를 사용할 때 코드 가독성이 향상됩니다.

willSet과 didSet의 작동 방식

실행 순서는 엄격하게 정의됩니다: 먼저 willSet(이전 값 사용 가능), 그 다음 할당, 그 다음 didSet(새 값 사용 가능)입니다.

swift
class Temperature {
    var celsius: Double = 0.0 {
        willSet {
            print("온도가 \(celsius)에서 \(newValue)(으)로 변경됩니다")
        }
        didSet {
            if celsius > 100.0 {
                print("끓는점을 초과했습니다!")
            }
        }
    }
}

중요한 제한 사항: 인스턴스 생성 시 프로퍼티 초기화 중에는 관찰자가 호출되지 않습니다. init 내부에서 값을 할당해도 willSet과 didSet이 트리거되지 않습니다. 이는 구성 단계에서 원치 않는 부작용을 방지합니다.

Apple Swift Blog(2025)에 따르면 이 동작은 setter가 생성자에서도 호출되는 다른 많은 언어와 다릅니다. Swift는 안전성을 선택합니다. 관찰자는 객체 초기화가 완료된 후에만 작동을 시작합니다.

중첩 호출 및 재귀

didSet 내부에서 프로퍼티를 변경하면 관찰자가 반복적으로 호출될 수 있습니다. Swift는 재귀를 차단하지 않으며, 프로그래머가 수동으로 제어해야 합니다.

swift
var counter: Int = 0 {
    didSet {
        if counter < 5 {
            counter += 1
        }
    }
}

이러한 코드는 종료 조건이 제공되지 않으면 스택 오버플로와 함께 완전한 재귀를 생성합니다. Stack Overflow Swift Community(2025)에 따르면 이는 property observers 작업 시 초보자가 범하는 가장 흔한 실수 중 하나입니다.

구조체 프로퍼티의 관찰자

구조체는 제한 없이 stored properties에 대해 willSet과 didSet을 지원합니다. 구조체는 값 유형이며, mutating 메서드 내에서 프로퍼티를 수정해도 관찰자가 트리거된다는 점을 기억하는 것이 중요합니다.

swift
struct Point {
    var x: Double = 0.0 {
        didSet {
            print("X가 \(x)(으)로 변경되었습니다")
        }
    }
    var y: Double = 0.0 {
        didSet {
            print("Y가 \(y)(으)로 변경되었습니다")
        }
    }
}

var point = Point()
point.x = 5.0

실제 프로젝트에서 관찰자 사용

프로퍼티 관찰자는 Swift 프로젝트에서 UI 동기화부터 데이터 유효성 검사 및 로깅에 이르기까지 광범위한 작업에 사용됩니다.

값 유효성 검사

didSet을 사용하면 잘못된 값이 설정된 직후에 롤백하거나 수정할 수 있습니다. 이는 Objective-C의 번거로운 setter를 대체하고 모델 수준에서 데이터 무결성을 보장합니다.

swift
var age: Int = 0 {
    didSet {
        if age < 0 || age > 150 {
            age = oldValue
        }
    }
}

UI 동기화

관련 프로퍼티가 변경되면 별도의 업데이트 메서드 호출 없이 인터페이스 요소를 자동으로 업데이트할 수 있습니다.

swift
var userName: String = "" {
    didSet {
        nameLabel.text = userName
    }
}

변경 로깅

willSet은 디버깅 또는 감사 목적으로 로깅에 편리합니다. 적용 전에 시간과 새 값을 기록하여 로그에 분석을 위한 원본 데이터가 포함되도록 보장할 수 있습니다.

objc.io(2025)에 따르면 property observers는 단방향 데이터 흐름을 가진 아키텍처에서 특히 유용하며, 모든 프로퍼티 변경이 추후 상태 재현을 위해 기록됩니다.

computed properties와 비교

Computed properties는 즉시 값을 계산하며 저장 공간이 없는 반면, willSet과 didSet은 실제 값을 가진 stored property에서 작동합니다.

특성Property ObserversComputed Properties
저장아니요
변경 시 코드 실행아니요
선언 유형varvar (get/set)
액세스 매개변수newValue, oldValuenewValue(set 내)
초기화초기값 필요필요 없음

주요 차이점: computed property는 액세스할 때마다 값을 계산하는 반면, property observer는 기존 값의 변경에 반응합니다. 이 둘 사이의 선택은 의미론에 따라 결정됩니다. 프로퍼티가 다른 데이터에서 파생된 경우 computed를 사용하고, 변경을 관찰해야 하는 독립적인 값인 경우 willSet/didSet을 사용합니다.

사용 시 일반적인 실수

가장 흔한 실수는 종료 조건 없이 didSet을 재귀적으로 호출하는 것입니다. didSet 내부의 각 프로퍼티 변경은 관찰자를 다시 트리거하여 무한 루프로 이어집니다.

두 번째 흔한 실수는 let 프로퍼티에 관찰자를 사용하려는 시도입니다. let은 상수이므로 Swift 컴파일러가 오류를 발생시킵니다.

세 번째 실수는 초기화 중에 관찰자가 호출되지 않는다는 점을 무시하는 것입니다. init 내에서 willSet이 실행될 것으로 예상하는 개발자는 예상치 못한 동작을 경험합니다.

네 번째 문제는 확장의 프로퍼티에 관찰자를 적용하는 것입니다. Swift는 확장에서 stored properties에 willSet/didSet을 추가하는 것을 금지합니다.

Ray Wenderlich(2025)에 따르면 이러한 제한 사항을 이해하면 초기 단계에서 버그를 방지하고 Swift 코드를 더 예측 가능하게 만듭니다.

자주 묻는 질문

didSet 없이 willSet을 사용할 수 있나요?

예, 관찰자는 선택 사항입니다. willSet만, didSet만, 또는 둘 다 동시에 선언할 수 있습니다.

확장에서 관찰자가 작동하나요?

아니요, Swift는 확장에서 stored properties에 willSet과 didSet을 추가하는 것을 금지합니다. 관찰자는 원래 유형 정의에서만 선언됩니다.

init 내에서 프로퍼티를 변경하면 관찰자가 호출되나요?

아니요, 초기화 중에는 관찰자가 호출되지 않습니다. 이는 객체 구성 단계에서 부작용을 방지하는 보호 메커니즘입니다.

willSet은 computed property의 setter와 어떻게 다른가요?

willSet은 값이 변경되기 전에 실행되는 stored property 관찰자입니다. computed property의 setter는 새 값을 계산하는 방법이지 기존 값을 관찰하는 방법이 아닙니다.

didSet 내에서 프로퍼티를 변경하면 어떻게 되나요?

반복적인 didSet 호출은 재귀를 유발합니다. 종료 조건 없이는 스택 오버플로와 프로그램 종료로 이어집니다.

요약

  • willSet — 프로퍼티 변경 전에 실행되는 관찰자, newValue에 액세스 가능
  • didSet — 프로퍼티 변경 후에 실행되는 관찰자, oldValue에 액세스 가능
  • 구문 — 관찰자는 프로퍼티 선언 후 중괄호 안에 선언됩니다
  • 초기화 — 관찰자는 init 내부 및 기본값 설정 시 작동하지 않습니다
  • 용도 — 유효성 검사, UI 동기화, 로깅, 변경 감사
  • 재귀 — didSet 내 프로퍼티 변경에는 명시적 종료 조건이 필요합니다
  • Computed — computed properties와 혼동하지 마세요: 관찰자는 관찰하고, computed는 계산합니다

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기