ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Combine - Subject
    Combine 2022. 2. 28. 09:51

    안녕하세요. 그린입니다🟢

    이번 포스팅에서는 Combine의 Subject에 대해 알아보겠습니다🙋🏻

     

    Subject?

    외부 호출자가 요소를 게시할 수 있도록 하는 메서드를 노출하는 게시자라고 공식문서에는 나와있습니다만..

    헷갈리는 말이네요 정말🥲

    간단히가 될지 모르겠지만 나름 해석을 해본다면 외부 호출자가 값을 퍼블리쉬 하도록 즉, 값을 방출 하도록

    도와주는 친구라고 해석하는게 심신 안정에 도움이 될것 같아요.

    선언을 보면 아래와 같이 Publisher 프로토콜을 채택하고 있어요.

    즉 이 친구도 Publisher의 개념이라 보면 될것 같습니다.

    protocol Subject : AnyObject, Publisher

    그리고 이 친구는 send(_:)라는 메서드를 가지고 스트림에 값을 에밋해줄 수 있도록 해줍니다.

    사실 이렇게만 설명하면 감이 잘 안오실것 같네요!

    한번 그러면 코드를 통해 아래에서 더 알아봅시다🙌

     

    Subject의 종류

    Subject 유형에는 두가지가 있습니다.

    PassthroughSubjectCurrentValueSubject가 있어요.

    두가지니까 맘 편하게 부담갖지 않고 한번 알아보죠!

    PassthroughSubject?

    다운스트림 Subscriber에게 값(이벤트)를 브로드캐스트(중계) 해주는 Subject입니다.

    선언부를 보면 요렇습니다.

    final class PassthroughSubject<Output, Failure> where Failure : Error

    해당 친구는 초기값과 버퍼가 없습니다.

    구독하고 있는 Subscriber들이 아예 없거나 수요가 0일때 값을 삭제해줍니다.

    코드로 보시죠!

    let subject = PassthroughSubject<String, Never>() 
    let subscriber = subject.sink(
      receiveValue: { print($0) }
     ) 
    
    subject.send("First") 
    subject.send("Second")
    subject.send("Third")
    
    // Fist
    // Second
    // Third

    위와 같이 사용되요.

    String을 Output으로 갖는 PassthroughSubject 인스턴스가 있고 이를 구독하는 subscriber가 있습니다.

    이 subscriber는 값을 받으면 그 값을 출력해주도록 설정했습니다.

    그리고 subject에 send메서드를 통해 값을 방출해줍니다.

    그러면 subscriber에서 프린트 동작을 수행합니다.

    요렇게 초기값이 없고 send를 통해 값들을 스트림에 방출해줍니다.

    CurrentValueSubject?

    단일 값을 래핑하고 값 변경 시 마다 새 값(이벤트)를 게시(Publish)해주는 Subject입니다.

    선언부를 요렇습니다.

    final class CurrentValueSubject<Output, Failure> where Failure : Error

    뭐 사실 PassthroughSubject와 크게 다를바 없어보이지만 차이는 있습니다.

    꼭 초기값을 줘야합니다. 없다면 컴파일 에러가 납니다.

    또한 제일 최근에 방출된 값을 버퍼에 저장합니다.

    send를 통해 값을 방출하면 최근 버퍼에 저장된 값도 해당 값으로 갱신됩니다.

    코드 보시죠!

    let subject = CurrentValueSubject<String, Never>("First") 
    let subscriber = subject.sink(
      receiveValue: { print($0) }
     ) 
    
    subject.value = "Second"
    subject.send("Third")
    subject.value = "Fourth"
    subject.send("Fifth")
    
    // Fist
    // Second
    // Third
    // Fourth
    // Fifth

    초기값을 인스턴스 생성 시 줘야합니다.

    그거빼고는 뭐 위에서 다룬것과 거의 동치에요.

    그리고 매번 value로 값을 바꾸던 send로 값을 방출하던 subject의 value는 최근 값으로 업데이트됩니다🙌

    send(completion:)

    위에서 send(_:) 요 메서드는 주구장창 다뤘어요.

    값을 방출해주잖아요?

    근데 send(completion:)은 뭘까요?

    이 메서드를 사용하면 subscriber에게 끝났다라는걸 알려줍니다.

    완료 신호를 보내주고 그에 대해서 subscriber에서는 처리할 수 있어요.

    다만 완료 신호를 준 이후 send(_:)로 값 확인하면 처리되지 않습니다!

    선언부는 요렇습니다.

    final func send(completion: Subscribers.Completion<Failure>)

    즉, 게시를 하고 정상적으로 완료되었는지 실패했는지 신호를 주고 그에 대한 처리가 가능하겠네요!

    마무리

    이번 포스팅에서는 이렇게 Subject에 대해 다뤄봤습니다!

    여러분 Combine 어렵지 않아요..!

    하나씩 익혀가봅시다ㅎㅎ

    [참고자료]

    https://developer.apple.com/documentation/combine/subject

     

    Apple Developer Documentation

     

    developer.apple.com

     

    'Combine' 카테고리의 다른 글

    Combine - Cancellable  (2) 2022.03.10
    Combine - Scheduler  (0) 2022.03.07
    Combine - Subscriber  (0) 2022.02.24
    Combine - Publisher  (0) 2022.02.22
    Combine  (0) 2021.06.09
Designed by Tistory.