[Combine] sink, assign 의 차이점

haram·2025년 2월 1일
post-thumbnail

공통점 :

  • sink와 assign모두 값을 구독하고 이를 처리하기 위한 방법이다.

차이점 :

  • sink : 값을 받아 처리하는 클로저를 전달받아 해당 값을 통한 로직 수행
  • assign : 값을 전달받아 특정 객체의 프로퍼티에 할당시킴

sink의 정의

  • subscriber을 직접 구현 할 필요없이 해당 publisher의 타입을 준수하는 subscriber을 반환해준다.
  • AnyCancellable프로토콜을 준수하는 subscriber를 반환하기 때문에 구독 취소를 할 수 있다.

sink예제

let myRange = (0...3)
cancellable = myRange.publisher
    .sink(receiveCompletion: { print ("completion: \($0)") },
          receiveValue: { print ("value: \($0)") })

// Prints:
//  value: 0
//  value: 1
//  value: 2
//  value: 3
//  completion: finished

assign(to:)의 정의

  • publisher로 부터 방출받은 값을 @Published가 붙은 인스턴스에서 재방출하기 위해 사용하는 연산자이다.
  • @Published가 붙은 인스턴스의 생명주기에 따라 subscription이 관리 되기 때문에 AnyCancellable인스턴스를 반환하지 않는다.

assign(to:)예제

  • Just를 통해 100이란 값을 방출하면 MyModel인스턴스 id에 값을 전달하는 코드
    class MyModel: ObservableObject {
        @Published var id: Int = 0
    }
    let model2 = MyModel()
    Just(100).assign(to: &model2.$id)

assign(to:on:)

  • publisher로 부터 방출받은 값을 특정 객체의 프로터티에 할당한다.
  • keyPath는 on의 객체에서 프로퍼티를 특정시키기 위한 인풋값이다.
  • AnyCancellable인스턴스를 반환하므로 프로퍼티에 값이 자동할당 되는 것을 중지하고 싶다면 cancell()함수를 호출하면 된다.

assign(to:on:) 예제

class MyClass {
    var anInt: Int = 0 {
        didSet {
            print("anInt was set to: \(anInt)", terminator: "; ")
        }
    }
}

var myObject = MyClass()
let myRange = (0...2)
cancellable = myRange.publisher
    .assign(to: \.anInt, on: myObject)

// Prints: "anInt was set to: 0; anInt was set to: 1; anInt was set to: 2"

0개의 댓글