SwiftUI - 생명주기(LifeCycle)

이재원·2024년 8월 4일
0

SwiftUI

목록 보기
9/9
post-thumbnail
post-custom-banner

SwiftUI의 생명주기

SwiftUI의 생명주기는 크게 앱의 생명주기와 뷰의 생명주기로 나눌 수 있습니다.

앱의 생명주기

1. 앱 초기화

@main 은 App 프로토콜을 따르는 구조체로, C나 java에서 main 함수와 같이 앱의 진입점이 됩니다.

만약 App 프로토콜을 명시하지 않는다면 컴파일 에러가 발생하기 때문에 꼭 함께 작성해 줘야 합니다.

또한 init() 메서드를 통해 앱의 초기 설정을 수행할 수 있습니다.

@main
struct MyApp: App {
    init() {
        // 앱 초기 설정
        print("App is initializing")
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

init() 메서드를 사용하는 이유는 앱 실행 전 초기화 해야 할 작업들을 수행하기 위해서 입니다.

예를 들어 앱이 시작될 때 네트워크를 연결하거나 초기 데이터를 받아오는 등의 작업을 처리할 수 있습니다.

@main
struct MyApp: App {
    init() {
        // 앱 초기 설정
        print("App is initializing")
        setupLogging()
        preloadData()
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }

    func setupLogging() {
        // 로깅 설정 코드
    }

    func preloadData() {
        // 초기 데이터 로드 코드
    }
}

이처럼 init() 메서드는 특정 작업을 앱 시작 전에 미리 해야 할 경우에 사용하기 때문에 없어도 앱을 실행하는데 문제가 되지 않습니다.

2. 앱 시작

body 속성에서 뷰 계층 구조의 루트를 설정합니다.

3. 앱 상태 변경(onChange)

앱의 상태가 변경될 때 실행할 코드를 정의할 수 있습니다.

import SwiftUI

@main
struct MyApp: App {
    @Environment(\.scenePhase) var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { newPhase in
            switch newPhase {
            case .active:
                print("App is active")
            case .inactive:
                print("App is inactive")
            case .background:
                print("App is in background")
            @unknown default:
                print("Unexpected state")
            }
        }
    }
}

뷰의 생명주기

뷰의 생명주기는 SwiftUI의 View 프로토콜을 따르는 구조체에서 관리됩니다.

주요 단계는 아래와 같습니다.

1. 뷰의 초기화

뷰가 생성될 때 초기 설정 수행합니다.

2. 뷰 렌더링

뷰의 내용을 정의하여 화면에 그릴 수 있도록 합니다.

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

3. 상태 변경 및 업데이트

뷰의 상태가 변경될 때마다 뷰가 다시 렌더링 됩니다.

struct ContentView: View {
    @State private var counter = 0

    var body: some View {
        VStack {
            Text("Counter: \(counter)")
            Button(action: {
                counter += 1
            }) {
                Text("Increment")
            }
        }
    }
}

4. 뷰 업데이트(onAppear, onDisappear)

뷰가 화면에 나타날 때와 사라질 때 실행할 코드를 정의할 수 있습니다.

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .onAppear {
                print("ContentView appeared!")
            }
            .onDisappear {
                print("ContentView disappeared!")
            }
    }
}

onAppear와 onDisappear의 정의는 다음과 같습니다.

onAppear

nonisolated
func onAppear(perform action: (() -> Void)? = nil) -> some View

공식문서에서 설명은 view가 나타날 때 수행할 action을 추가한다고 되어 있습니다.

perfome은 옵셔널이기 때문에 아무것도 작성하지 않는 것도 가능합니다.

onDisappear

nonisolated
func onDisappear(perform action: (() -> Void)? = nil) -> some View

onDisappear도 onAppear과 정의는 같습니다..

따라서 onAppear은 화면이 나타날때 호출되는 함수이고, onDisappear은 화면이 사라질 때 호출되는 함수라는 것 외에 사용법은 동일합니다.

5. 뷰 제거

뷰가 메모리에서 제거될 때 정리 작업을 수행합니다.

아래는 SwiftUI의 뷰 생명주기를 보여주는 전체 코드입니다.

import SwiftUI

@main
struct MyApp: App {
    @Environment(\.scenePhase) var scenePhase

    init() {
        print("App is initializing")
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { newPhase in
            switch newPhase {
            case .active:
                print("App is active")
            case .inactive:
                print("App is inactive")
            case .background:
                print("App is in background")
            @unknown default:
                print("Unexpected state")
            }
        }
    }
}

struct ContentView: View {
    @State private var isPresented = false

    var body: some View {
        VStack {
            Text("Hello, World!")
                .onAppear {
                    print("ContentView appeared!")
                }
                .onDisappear {
                    print("ContentView disappeared!")
                }

            Button(action: {
                isPresented.toggle()
            }) {
                Text("Toggle View")
            }
            
            if isPresented {
                SecondView()
            }
        }
    }
}

struct SecondView: View {
    var body: some View {
        Text("This is the second view")
            .onAppear {
                print("SecondView appeared!")
            }
            .onDisappear {
                print("SecondView disappeared!")
            }
    }
}

생명주기 요약

  • 앱 생명주기:
    • @main: 앱의 진입점으로, App 프로토콜을 준수해야 합니다.
    • 초기화: init() 메서드를 사용하여 앱의 초기 설정을 수행합니다.
  • 뷰 생명주기:
    • 초기화: 뷰가 생성될 때 초기 설정을 수행합니다.
    • 렌더링: body 속성에서 뷰의 내용을 정의하여 화면에 그립니다.
    • 상태 변경 및 업데이트: @State, @Binding, @Environment 등을 사용하여 뷰의 상태가 변경될 때마다 뷰를 다시 렌더링합니다.
    • 뷰 생명주기 이벤트: onAppearonDisappear를 사용하여 뷰가 화면에 나타날 때와 사라질 때 실행할 코드를 정의합니다.
    • 제거: 뷰가 메모리에서 제거될 때 정리 작업을 수행합니다.

마무리

오늘은 SwiftUI의 생명주기에 대해 알아봤습니다.

대략적으로 알고는 있었지만, 이렇게 글로 정리해 보는건 처음이네요.

생명주기를 알면 앱의 전체 흐름을 이해할 수 있기 때문에 중요한 부분인거 같습니다. 흐름을 이해한다는 것은 예상치 못한 오류가 발생하여도 오류를 제거하기가 수월해지고, 뿐만 아니라 앱을 효율적으로 만들 수도 있기 때문입니다.

이 글을 읽는 분들도 개념 정리가 잘 되었으면 좋겠습니다.

출처
https://velog.io/@luke_kong/SwiftUI-생명주기-이벤트-핸들링의-모든-것
https://zeddios.tistory.com/936
https://developer.apple.com/documentation/swiftui/view/ondisappear(perform:)
https://developer.apple.com/documentation/swiftui/view/onappear(perform:)

profile
20학번 새내기^^(였음..)
post-custom-banner

0개의 댓글