티스토리 뷰

Combine

Combine (4) - Cancellable

Zedd0202 2020. 3. 24. 15:05
반응형

 

안녕하세요 :) Zedd입니다.

오늘은..

 

마지막..!! Cancellable을 공부해볼게요!

Combine을 공부하고 그걸 블로그에 포스팅 하는 입장으로서, 틀린 내용을 게시하지 않으려고 노력중입니다!

그럼에도 불구하고 틀린 내용이 있을 수 있으니

이 글만 보고 아 이게 이렇구나~라는 건 굉장히 위험합니다. 

그걸 꼭 염두하시고 글을 읽으시길 바랄게요 :D

틀린 내용을 발견하시면 댓글로 알려주시면 감사하겠습니다!

Combine이 유독......뭔가 조심스럽네요. 제가 1도 몰라서리 ㅎ

 

그럼 Cancellable을 공부해봅시다!

Cancellable 역시 프로토콜이구요! 

정의는 activity 또는 action이 취소(cancellation)를 지원함을 나타내는 프로토콜이라고 합니다..!

cancel()을 호출하면 할당 된 모든 리소스가 해제된대요.

타이머, 네트워크 액세스, 디스크 IO와 같은 부작용을 막는다고 해요.

 

이 Cancellable은 우리가..? 아니..제가..공부 한 적은 없지만 많이 봤어요!!

바로 sink의 result...

ㅇ ㅏ Cancellable인 줄 ㅎ AnyCancellable이네

그럼 AnyCancellable을 공부해봅시다!

AnyCancellable은 프로토콜은 아니고 class인데요.

딱 봐도 Cancellable 채택하게 생겼다 아님

응 맞아

AnyCancellable은 취소 되었을 때, 제공된 closure를 실행하는 type-erasing cancellable object입니다.

Subscriber 구현에서는 이 타입을 사용해서 caller가 publisher를 취소할 수 있지만, Subscription 객체를 사용하여 item을 요청할 수 없는 "cancellation token"을 제공할 수 있습니다. 

AnyCancellable 인스턴스는 deinitialized 될 때 자동으로 cancel()을 호출합니다.

 

자..! 그럼 cancel()을 명시적으로 호출해봅시다.

별로 어렵진 않은데요, 

이렇게 하면 되겠죠?!?!

send를 호출해도 아무 반응 없음 ㅎ 왜냐면 cancel 됐으니까..!!!

AnyCancellable의 생성자는 cancel()이 호출될 때 실행할 closure를 받는데요, sink에서...알아서 넣겠죠..!?

실제로, subscriber를 dump해보면..

이렇게 나옵니다.

cancel하고 나서는

이러케 nil...

 

그럼 제가 궁금한 점은..

sink로 subscriber를 만들었는데...cancel()을 호출했어.

근데 내가 원하는 클로져 실행시키고 싶어 < 이거 안되는건가요...!?!?!

저 클로져 안에 뭐가 들어있는거지..?

 

자..cancel되었을 때 내 closure를 실행시키는 방법은 이 글 후반부에서 다루도록 할게요.

먼저 Cancellable의 store(in: ) 메소드를 보도록 할게요!

자 store(in: ) 메소드는 뭐냐면..말그대로 store..저장하는 겁니다.

뭐를? Cancellable instance를...

그래서 어떻게 사용하면 되냐면..

store메소드안에 보면 파라미터의 타입이 Set<AnyCancellable>인걸 볼 수 있죠?  

응 그니까 Set<AnyCancellable>을 만들어주고, 그걸 그냥 store에 넘기면 됩니다. 짱쉽죠...

 

아무튼 store(in: )메소드의 사용법은 알겠죠? 

그럼 Subscription객체를 이용해서..취소되었을 때 내가 실행하고 싶은 closure를 실행하는 방법을 볼게요 ㅎㅎ

자..custom Subscriber를 만들어주었습니다. https://zeddios.tistory.com/966 

 

Combine (1-1) - Subcribers.Demand

안녕하세요 :) Zedd입니다. https://zeddios.tistory.com/925 Combine (1) - Publisher, Subscriber 안녕하세요 :) Zedd입니다. 이번 휴가동안 SwiftUI를 좀 해볼라하는데 Combine모르면 이거 걍 노답임.... -> 휴..

zeddios.tistory.com

에서 조금 수정한 예제에요. 위 글을 보신 분이라면..익숙하실거에요.

위 코드에서 눈여겨 봐야 할 점은, 

Subscription 타입 변수가 있다는 겁니다!

이 Subscription 역시 프로토콜이구요. Subscription은 Cancellable을 채택하고 있습니다. 

그럼 custom Subscription 타입을 만들어볼게요. 

https://github.com/sumitoberoi1/SwiftUI/blob/60e0536d0b06edd29dfc4eb126ba19b7d99f199f/SwiftUI-Flux/Models/AnySubscription.swift

를 참고했어요! (클래스 이름만 바꿈)

그럼 ZeddSubscription 인스턴스를 만들어서 ZeddSubscriber의 subscription안에 넣어주면 되겠죠?

이렇게 해줘볼게요!

subscribe앞에 print()를 호출했기 때문에 실행하면 콘솔에 로그들이 뜰거에요! 저번글에서는 단순히 print().~이런식으로 했는데 오늘은

print 안에 그냥 아무 String을 넣어봤어요~ 이렇게도 쓸 수 있다는 걸 알려드리고 싶었습니다..!

이렇게 뜨게 됩니다 ㅎㅎㅎ

자, 그럼 cancel되었을 때 "cancel!" 이 출력된 걸 볼 수 있죠!!!

내가 넣은 클로져가 실행이 되었습니다!!!

근데 지금 이거는..custom Subscriber만들고..

custom Subscription까지 만들어서......ㅎㅎㅎ 한거잖아요..!! 귀찮귀찮

Apple이 제공해주는 subscriber를 만들어주는 sink..를 가지고 cancel 되었는지 어쩐지를 판별을 어떻게 할 수 있을까요!?

 

찾아보니 handleEvent라는게 있어요!

정의는

"Performs the specified closures when publisher events occur." 

publisher 이벤트가 발생 할 때 지정한 closure를 수행한다...입니다!

사용방법을 볼게요!

이렇게 사용하시면 됩니다. 

당연히 sink를 써서;; 구독을 해야 send고 뭐고 작동을 하겠죠?

아 근데 진짜 아쉬운게 sink안에 있으면 안되는거야..>!?!?!?!?!?!

코드가 쓸데없이 길어지는 느낌인데..ㅠㅠ 

그래도 있는게 어디..라며...

감사해봅니다...

 

일단 제가 대충 정한..그러니까 Combine의 가장 대표적인 프로토콜들은 다 공부를 했네요..!

그래도 봐야 할게 엄청나게 많이 남았지만..ㅎㅎ 도움이 되었길 바랍니다.

 

참고 

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

 

Cancellable - Combine | Apple Developer Documentation

A type-erasing cancellable object that executes a provided closure when canceled.

developer.apple.com

https://www.avanderlee.com/debugging/combine-swift/

 

Combine debugging using operators in Swift - SwiftLee

Combine debugging can be hard because of the long stack traces and asynchronous callbacks. Learn how to benefit from Combine operators to solve this issue.

www.avanderlee.com

 

반응형

'Combine' 카테고리의 다른 글

Combine ) ConnectablePublisher  (0) 2020.04.26
Combine + UIKit  (2) 2020.04.19
Combine (3) - Scheduler  (4) 2020.03.23
Combine (2) - Subject  (0) 2020.02.29
Combine (1-1) - Subcribers.Demand  (0) 2020.02.26