Machineboy空

Combine이란? - Publisher, Subsciber(store, sink, AnyCancellable) 본문

카테고리 없음

Combine이란? - Publisher, Subsciber(store, sink, AnyCancellable)

안녕도라 2024. 5. 14. 12:57

비동기 프로그래밍을 하는 이유

네트워크 요청, 데이터 로딩, 이미지 처리 등 시간이 소요되는 작업을 비동기적으로 처리함으로써 앱의 반응성을 높일 수 있다.

비동기 프로그래밍을 통해 메인 스레드를 차단하지 않고 백그라운드에서 작업을 수행할 수 있기 때문에 UI가 멈추지 않고 부드럽게 동작한다.


Combine이란?

iOS개발에서 비동기 프로그래밍을 구현하는 방법 중의 하나인 Combine 프레임워크.

Swift에서 제공하는 선언적 Swift API로 비동기 프로그래밍을 간결하고 효율적으로 구현할 수 있게 해준다.

 

  • Publisher
    • 값이나 이벤트를 생성할고 방출하는 역할
    • 데이터 스트림의 출처
    • 다양한 이벤트 생성
  • Subscriber
    • Publisher로부터 방출된 값을 수신하여 처리하는 역할
    • 데이터 스트림의 소비자
    • 수신된 데이터에 대한 반응을 정의

Publisher와 Subscriber 사이의 연결을 통해 비동기 이벤트를 효율적으로 처리하는 것이 Combine 프로그래밍의 핵심

 

다른 비동기 패턴들에 비해 코드의 가독성과 유지보수성을 향상시킴


import Combine
import Foundation

    class DataLoader {
        var cancellables: Set = []

        func loadData() {
            let url = URL(string: "https://example.com/data")!
            
            // URLSession의 dataTaskPublisher 메소드를 사용하여 네트워크 요청을 Publisher로 변환
            URLSession.shared.dataTaskPublisher(for: url)
                //map과 decode 연산자를 사용하여 네트워크 응답을 원하는 데이터 모델로 변환
                .map { $0.data }
                .decode(type: DataModel.self, decoder: JSONDecoder())
                //sink 메소드를 사용하여 최종 데이터를 수신
                //sink는 Subscriber의 역할을 하여 Publisher로부터 방출된 값을 처리
                .sink(receiveCompletion: { completion in
                    switch completion {
                    case .finished:
                        break
                    case .failure(let error):
                        print(error.localizedDescription)
                    }
                }, receiveValue: { dataModel in
                    print(dataModel)
                })
                .store(in: &cancellables)
        }
    }

데이터 스트림이란?

Publisher에서 연결되어 Subscriber까지 이어지는 데이터의 흐름.

시간에 따라 연속적으로 발생하는 데이터 시퀀스

 

  • 업스트림(UpStream): 데이터 소스 발생지
  • 다운스트림(DownStream): 데이터가 처리되고 소비되는 지점

 

근데 지금 내가 알고 싶은 건, AnyCancellable이 뭐냐는 거다..

너무 잘 정리 되어있는 notion을 찾았다. 사람들은 천사인가보다..

 

https://medium.com/@bbuyo/뿌요와-함께하는-combine-publisher-f78d44215ff5

 

뿌요와 함께하는 Combine — Publisher

Publisher란?

medium.com

 

https://admitted-peripheral-8ed.notion.site/Combine-c33cd5c227b7488f87a563c227fbc4a1

 

뿌요와 함께하는 Combine | Notion

🦘 Inspired by Wallaby와 함께하는 RxSwift

admitted-peripheral-8ed.notion.site

 


AnyCancellable이란?

 

AnyCancellable은 Cancellable이라는 프로토콜의 구현체로, 메모리 관리와 리소스 관리 차원에서 굉장히 중요한 역할을 담당한다.

 

Cancellable은 cancel()이라는 메서드를 가지고 있는데,

이 메서드를 호출하면 구독이 취소되고 Publisher로부터 더 이상 데이터 스트림을 받지 않는다.

구독을 취소하지 않으면 메모리 누수가 발생하게 되어 앱 성능이 떨어지게 된다.

 

var cancellables = Set<AnyCancellable>()

Just("Hello, Combine!")
    .sink {
	    ...
    } receiveValue: {
	    ...
    }
    .store(in: &cancellables) // !

 

프로세스 요악

  1. .sink 메서드 사용과 동시에 구독을 시작
  2. 이때 구독(subscription)을 취소할 수 있는 AnyCancellable 객체가 리턴
  3. 이 AnyCancellable 객체를 .store로 Set에 저장
  4. Set이 메모리에서 해제될 때 여기에 담겼던 AnyCancellable이 cancel()을 호출.

sink 에서 AnyCancellable 객체가 리턴됌!

 

.store를 사용하지 않는다면?

let cancellable = Just("Hello, Combine!")
    .sink(receiveValue: { value in
        print(value)
    })

 

모든 구독관계에 대해 컨트롤하기 귀찮기 때문에 한번에 처리될 수 있는 쓰레기 처리장 (set)에 구독 삭제 발생장치(AnyCancellable)을 적재하는 함수 store가 있는 것!