From f37eb4c7e7a4a08847789ccd1b2b71ee5b064192 Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Fri, 6 Jun 2025 17:06:42 -0700 Subject: [PATCH] Explain cancellables in AsyncMonitor and NotificationSmuggler post --- ...nd-async-stream-monitoring-with-swift-6.md | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/posts/2025/06/type-safe-notifications-and-async-stream-monitoring-with-swift-6.md b/posts/2025/06/type-safe-notifications-and-async-stream-monitoring-with-swift-6.md index 5876881..5b1e388 100644 --- a/posts/2025/06/type-safe-notifications-and-async-stream-monitoring-with-swift-6.md +++ b/posts/2025/06/type-safe-notifications-and-async-stream-monitoring-with-swift-6.md @@ -45,16 +45,36 @@ The `monitor` method creates a `Task` internally and handles cleanup when the ca You're free to do the usual `[weak self]` and `guard let self else { return }` dance, but there's a variant that accepts a context parameter that's automatically weakified. Your closure receives a strong reference: ```swift -NotificationCenter.default +let cancellable = NotificationCenter.default .notifications(named: .NSCalendarDayChanged) .map(\.name) .monitor(context: self) { _self, _ in _self.dayChanged() - }.store(in: &cancellables) + } ``` The monitor finishes automatically after finding a nil context. +### Cancellation tokens + +Similar to Combine there's the concept of a cancellable that ties the observation to the lifetime of that cancellable instance. And of course, we call it a dispose bag. Just kidding obviously, it's called `AsyncCancellable` and there's an `AnyAsyncCancellable` type-erasing wrapper. So very much like Combine you write this: + +```swift +import AsyncMonitor + +class Whatever { + private var cancellables: Set = [] + + func something() { + NotificationCenter.default + .notifications(named: .NSCalendarDayChanged) + .map(\.name) + .monitor { _ in /* ... */ } + .store(in: &cancellables) + } +} +``` + ### KVO Sometimes you need KVO and the old ways are best. There's a KVO extension that bridges to async sequences: