iOS 개발 기록

[Swift]Combine - Publisher, Subscriber, NotificationCenter 본문

Swift

[Swift]Combine - Publisher, Subscriber, NotificationCenter

택꽁이 2022. 4. 18. 20:32
728x90

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

RX와 같은 비동기 이벤트를 처리하기  위한 프레임워크. iOS13부터 사용 가능하고, iOS13 이전 버전은 RX를 사용해야 한다. 

 


Publisher 

import Combine

var IntArrayPublisher: Publishers.Sequence<[Int], Never> = [1,2,3].publisher

 

RX의 Obsevable. 관찰 가능한 대상으로 데이터를 전달함. 전달할 때에 제네릭 형태로 <데이터, 에러타입>으로 같이 보낸다. 에러 타입 중에 Never이 있는데, 얘는 어떠한 에러도 발생 안시킨다. 

 

 

 

 

 Subscriber 

IntArrayPublisher.sink(receiveCompletion: { completion in
    switch completion {
    case .finished:
        print("완료")
    case .failure(let err):
        print("실패: \(err)")
    }
}, receiveValue: { recievedValue in
    print("값 받음. : \(recievedValue)")
})

sink() 정의

 Publisher랑 연결이 되어있는 이벤트를 전달받는 대상. sink()를 통해 구독할 수 있고, completion을 통해 에러 정보와 값을 전달받을 수 있다. 위의 코드에서 에러를 Never로 입력했기 때문에 사실 Error가 나와도 리턴 안한다.

 

Swift에서는 Combine을 통해 구현한 기능들을 이미 제공하고 있는데 대표적인 예가 Timer나 NotificationCenter, URLSession 이다. 

 

 

 

 

NotificationCenter

var notification = Notification.Name("com.Leetak.customNotification")
var defaultPublisher: NotificationCenter.Publisher = NotificationCenter.default.publisher(for: notification)

// sink를 변수에 할당할 경우에 사용할 변수와 해제하기 위한 Set
var subscription: AnyCancellable?
var subscriptionSet = Set<AnyCancellable>()

// 이벤트를 받음
defaultPublisher.sink(receiveCompletion: { completion in
    switch completion {
    case .finished :
        print("완료")
    case .failure(let err):
        print("실패: \(err)")
    }
}, receiveValue: { recievedValue in
    print("값 받음. : \(recievedValue)")
}).store(in: %subscriptionSet)       // 데이터를 메모리에서 해지


// 이벤트를 보냄
NotificationCenter.default.post(Notification(name: notification))
NotificationCenter.default.post(Notification(name: notification))
NotificationCenter.default.post(Notification(name: notification))


// 데이터를 메모리에서 해제하는 2가지 방법
//1. Set을 이용해 메모리 해제
// 보통은 위의 코드와 같은 방법으로 사용
//subscripion?.store(in: &subscriptionSet)

//2. 메모리 해지 수동으로 해제
//subscription?.cancel()

Notification의 이벤트가 발생할 경우 이를 받고 처리하는 방법 또한 Combine을 통해 이루어 진다. Subscription의 경우 어딘가에 저장해두지 않으면 메모리에서 헤제되어 동작하지 않는데, AnyCancellable 프로토콜의 경우 Subscription을 store() 하기 위해 사용된다.  (위의 sink() 의 정의를 보면 AnyCancellable타입으로 반환한다!) 

삭제하기 위해서 Set을 사용한다는데 그 이유는 좀 더 찾아봐야겠다 ... 

 

 

'Swift' 카테고리의 다른 글

[iOS] PencilKit  (0) 2022.07.07
Swift 의 메모리 관리 (ARC, weak, unowned, lazy)  (0) 2022.05.31
Swift의 특징과 프로그래밍 패러다임  (0) 2022.05.31
KVC와 KVO란?  (0) 2022.05.31
Swift - Opaque Type ( 불투명 반환 타입 )  (0) 2022.04.14