combine에서 @Published는 값이 바뀔때마다 방출을 하는데 이때 방출되는 시점은 언제일까 ??

당연히 didSet이 호출되어 값이 바뀌고 난 뒤라고 생각했는데 실제 값과 receive된 값이 다르다는 걸 알게 되었다.

//
//  ContentView.swift
//  Test
//
//  Created by 이준복 on 6/20/25.
//

import SwiftUI
import Combine

struct ContentView: View {
    
    @StateObject
    private var viewModel = ViewModel()
    
    var body: some View {
        VStack {
            Text("Count: \(viewModel.count)")
                .font(.largeTitle)
            
            Button("Increment") {
                viewModel.increment()
            }
        }
        .padding()
    }
    
}

#Preview {
    ContentView()
}


class ViewModel: ObservableObject {
    
    @Published
    var count: Int = 0 {
        willSet {
            print("willSet: \(count)")
        }
        
        didSet {
            print("didSet: \(count)")
        }
    }
    
    private var cancellables = Set<AnyCancellable>()
    
    init() {
        $count
            .sink { [weak self] value in
                print("receive: \(value)", "real: \(self?.count ?? -1)")
            }
            .store(in: &cancellables)
    }

    func increment() {
        print("변경 전: \(count)")
        count += 1
        print("변경 후: \(count)")
    }
    
}

 

 

코드를 실행하기 전 결과를 예상 했을땐 아래라고 생각했는데 실제 결과 값은 그렇지 않았다.

변경 전: 0
willSet: 0
didSet: 1
receive: 1 real: 0
변경 후: 1

 

 

실제 결과 값

 

조금 찾아보니 willSet에서 .send(newValue)를 호출하여 값을 방출하는 것 같았다. 실제 메모리 반영되고 값이 바뀐 시점은 didSet 시점이니 이 부분을 알고 있으면 좋을 것 같다.

+ Recent posts