-
SwiftUI Preview - ThunkSwiftUI 2025. 11. 29. 21:38
안녕하세요. 그린입니다 🍏
이번 포스팅에서는 SwiftUI Preview가 어떻게 코드 변경을 실시간으로 반영하는지 그 내부 구조를 깊게 파헤쳐보려고 합니다 🙋🏻

Preview is not magic
SwiftUI Preview는 마치 마법처럼 알아서 짠하고 작동하는것처럼 보이죠.
struct ContentView: View { var body: some View { Text("Hello") // If you change this } } #Preview { ContentView() // It will be update immediately }앱 전체를 다시 빌드하지 않아도 Preview가 즉시 반영되는 이유는 바로 Xcode가 자동 생성하는 Preview-Thunk 파일(
.preview-thunk.swift)에서 찾을 수 있습니다.아래에서 하나씩 아주 자세히 설명해볼게요.
Preview-Thunk?
SwiftUI Preview를 활성화하면, Xcode는 우리가 작성한 Swift 파일과 별도로 Preview 전용 Thunk 파일을 자동 생성합니다.
이 파일은 Preview 갱신을 위해 필요한 동적 메서드 교체(dynamic replacement) 용 코드로 구성됩니다.
경로는 이렇습니다 😃
~/Library/Developer/Xcode/DerivedData/ └── <Project>/ └── Build/Intermediates.noindex/ └── Previews/ └── <Module>/ └── Objects-normal/ └── x86_64/ └── ContentView.1.preview-thunk.swift즉, Preview는 우리가 작성한 코드를 직접 실행하는 게 아니라
"Thunk 파일 → Thunk 컴파일 → Preview 프로세스에 로드" 과정을 거쳐 동작합니다.
Preview에 실제 생성되는 Thunk 코드
원본 코드
struct ContentView: View { var body: some View { Text("Hello, world!") } } #Preview { ContentView() }생성된 .preview-thunk.swift
#if DEBUG extension ContentView { @_dynamicReplacement(for: body) private var __preview__body: some View { AnyView( __designTimeSelection( Text( __designTimeString("#7464", fallback: "Hello, world!") ), "#7464" ) ) } } #endif
Preview-Thunk의 핵심 요소 분석
1️⃣ @_dynamicReplacement — 런타임 메서드 교체의 핵심
@_dynamicReplacement(for: body)Swift가 제공하는 기능으로, 기존 메서드를 새로운 구현으로 교체할 수 있게 해주는 기능입니다.
Preview는 이 기능을 이용해 View의
body를 실시간으로 교체합니다.- 앱 전체 재실행 필요 없음
body만 빠르게 교체 가능- Swizzling과 유사하지만 Swift 컴파일러가 안전하게 관리하는 방식
SwiftUI Preview 실시간 업데이트의 핵심 기술입니다.
2️⃣ __designTimeString — 문자열 변경 즉시 반영
문자열을 변경하면 Preview가 빌드 없이 즉시 반영되는 이유입니다.
Text(__designTimeString("#hash", fallback: "Hello, world!"))- 문자열 변경은 전체 재컴파일 없이 Preview만 바로 갱신
- Xcode가 소스 파일에서 문자열만 다시 파싱해서 Preview에 반영
- "Hello" → "Hi" 같은 변경은 0.1초 미만의 속도로 반영됨
3️⃣ #sourceLocation — 오류 표시를 정확하게
Thunk 파일은 실제 소스 파일이 아니기 때문에
에러 발생 시 원래 소스 파일 위치를 알려줄 필요가 있습니다.#sourceLocation(file: "/Users/.../ContentView.swift", line: 5)이 기능 덕분에 Preview에서 에러가 나도 정확한 파일·라인에 빨간줄이 표시됩니다.
4️⃣ @_private(sourceFile:) — private 코드 접근을 위한 장치
Preview는
private선언까지 읽어야 하는 경우가 많기 때문에 특수한@_privateimport가 추가됩니다.Preview 업데이트 3단계 전략
SwiftUI Preview는 변경 수준에 따라 세 가지 방식으로 업데이트 전략을 나눕니다.
1단계: Small Changes (가장 빠름)
- 문자열 리터럴 변경
- 재컴파일 없음
- 즉시 반영
- 예시: "Hello" → "Hi"
2단계: Middle Changes (Thunk만 재컴파일)
body내부 레이아웃·구현 변경- 함수 내용 변경
- → thunk 파일만 재컴파일
- Preview 프로세스 재시작 ❌
- 예시: VStack → HStack
3단계: Large Changes (전체 Preview 빌드)
- 새로운 stored property 추가
- 타입 구조 변경
- 함수 시그니처 변경
- Access level 변경
이 경우 Preview가 멈추고 Resume 버튼이 뜨는 것이 정상입니다.
Preview Process Structure
SwiftUI Preview는 앱 프로세스와 분리된 독립 프로세스에서 실행됩니다.
Xcode ↓ (XPC) Preview App Process ├─ App 모듈 └─ Thunk Dylib (dlopen)프로세스 구조는 다음과 같습니다.
- Xcode가 Previews 전용 빌드를 생성
- 각 Swift 파일마다
preview-thunk.swift생성 - thunk를 dylib으로 빌드
- Preview 프로세스가 dylib을
dlopen() @_dynamicReplacement가 원래 body를 교체- Xcode와 XPC로 통신
- Canvas 화면 반영
Conclusion
SwiftUI Preview는 단순한 화면 렌더링이 아니라 Thunk 생성 → Dynamic Replacement → Dylib 로딩 → XPC 통신이라는 매우 고도화된 시스템으로 구성되어 있습니다.
오늘 정리한 핵심 포인트는 다음과 같습니다.
- Preview는
.preview-thunk.swift파일을 자동 생성한다 @_dynamicReplacement로 body를 교체한다- 문자열 변경은 재컴파일 없이 즉시 반영된다
- 구조적 변경은 Preview 전체 재빌드가 필요하다
- Preview는 별도 프로세스로 실행되며 XPC로 Xcode와 통신한다
SwiftUI Preview의 속도나 동작이 궁금했다면 이제 내부 구조를 잘 이해하셨을 거라 생각합니다 😊
References
Behind SwiftUI Previews | Guardsquare
In this blog, we take a look under the hood of SwiftUI Previews and discuss the language features that were added to make SwiftUI Previews possible.
www.guardsquare.com
Building Stable Preview Views - How SwiftUI Previews Work
Explore SwiftUI preview's mechanism and limitations. Learn how it works via derived code, dynamic replacement, and XPC. Discover why previews crash & how to fix it.
fatbobman.com
How SwiftUI Preview Works Under the Hood
A deep dive into how SwiftUI Preview works in Xcode 16, including the build process, JIT execution mechanism, and three different rebuild strategies. Understanding these principles not only helps solve common Preview issues but also enables developers to b
onee.me
'SwiftUI' 카테고리의 다른 글
SwiftUI's diffing (5) 2025.09.27 Ensuring 60fps Animations in SwiftUI (GPU Rendering Optimization) (0) 2025.08.23 Bring Swift Charts to the third dimension (feat. WWDC 2025) (6) 2025.07.12 What's new in SwiftUI (feat. WWDC 2025) (3) 2025.06.11 Marquee (0) 2025.03.18