Skip to content

Commit bc05e17

Browse files
committed
Add documentation comments on most public API
1 parent b8eb878 commit bc05e17

5 files changed

Lines changed: 63 additions & 22 deletions

File tree

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
/// Type-erasing wrapper for ``AsyncCancellable`` that ties its instance lifetime to cancellation. In other words, when you release
2+
/// an instance of ``AnyAsyncCancellable`` and it's deallocated then it automatically cancels its given ``AsyncCancellable``.
13
public class AnyAsyncCancellable: AsyncCancellable {
24
let canceller: () -> Void
35

4-
init<AC: AsyncCancellable>(cancellable: AC) {
6+
public init<AC: AsyncCancellable>(cancellable: AC) {
57
canceller = { cancellable.cancel() }
68
}
79

@@ -14,14 +16,4 @@ public class AnyAsyncCancellable: AsyncCancellable {
1416
public func cancel() {
1517
canceller()
1618
}
17-
18-
// MARK: Hashable conformance
19-
20-
public static func == (lhs: AnyAsyncCancellable, rhs: AnyAsyncCancellable) -> Bool {
21-
ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
22-
}
23-
24-
public func hash(into hasher: inout Hasher) {
25-
hasher.combine(ObjectIdentifier(self))
26-
}
2719
}
Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,29 @@
1-
public protocol AsyncCancellable: Hashable {
1+
/// Represents an async operation that can be cancelled.
2+
public protocol AsyncCancellable: AnyObject, Hashable {
3+
/// Cancels the operation.
24
func cancel()
35

6+
/// Stores this cancellable in the given set, using the type-erasing wrapper ``AnyAsyncCancellable``. This method has a
7+
/// default implementation and you typically shouldn't need to override it.
48
func store(in set: inout Set<AnyAsyncCancellable>)
59
}
610

11+
// MARK: Default implementations
12+
713
public extension AsyncCancellable {
814
func store(in set: inout Set<AnyAsyncCancellable>) {
915
set.insert(AnyAsyncCancellable(cancellable: self))
1016
}
1117
}
18+
19+
// MARK: Hashable conformance
20+
21+
public extension AsyncCancellable {
22+
static func == (lhs: Self, rhs: Self) -> Bool {
23+
ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
24+
}
25+
26+
func hash(into hasher: inout Hasher) {
27+
hasher.combine(ObjectIdentifier(self))
28+
}
29+
}

Sources/AsyncMonitor/AsyncMonitor.swift

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
1+
/// A monitor that observes an asynchronous sequence and invokes the given block for each received element.
2+
///
3+
/// The element must be `Sendable` so to use it to monitor notifications from `NotificationCenter` you'll need to map them to
4+
/// something sendable before calling `monitor` on the sequence. e.g.
5+
///
6+
/// ```
7+
/// NotificationCenter.default
8+
/// .notifications(named: .NSCalendarDayChanged).map(\.name)
9+
/// .monitor { _ in whatever() }
10+
/// .store(in: &cancellables)
11+
/// ```
112
public final class AsyncMonitor: Hashable, AsyncCancellable {
213
let task: Task<Void, Never>
314

15+
/// Creates an ``AsyncMonitor`` that observes the provided asynchronous sequence.
16+
///
17+
/// - Parameters:
18+
/// - isolation: An optional actor isolation context to inherit.
19+
/// Defaults to `#isolation`, preserving the caller's actor isolation.
20+
/// - sequence: The asynchronous sequence of elements to observe.
21+
/// - block: A closure to execute for each element yielded by the sequence.
422
public init<Element: Sendable>(
523
isolation: isolated (any Actor)? = #isolation,
624
sequence: any AsyncSequence<Element, Never>,
@@ -21,17 +39,8 @@ public final class AsyncMonitor: Hashable, AsyncCancellable {
2139

2240
// MARK: AsyncCancellable conformance
2341

42+
/// Cancels the underlying task monitoring the asynchronous sequence.
2443
public func cancel() {
2544
task.cancel()
2645
}
27-
28-
// MARK: Hashable conformance
29-
30-
public static func == (lhs: AsyncMonitor, rhs: AsyncMonitor) -> Bool {
31-
lhs.task == rhs.task
32-
}
33-
34-
public func hash(into hasher: inout Hasher) {
35-
hasher.combine(task)
36-
}
3746
}

Sources/AsyncMonitor/AsyncSequence+Extensions.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
11
public extension AsyncSequence where Element: Sendable, Failure == Never {
2+
/// Observes the elements yielded by this sequence and executes the given closure with each element.
3+
///
4+
/// This method preserves the actor isolation of the caller by default when `isolation` is not specified.
5+
///
6+
/// - Parameters:
7+
/// - isolation: An optional actor isolation context to inherit. Defaults to `#isolation`, preserving the caller's actor isolation.
8+
/// - block: A closure that's executed with each yielded element.
29
func monitor(
310
isolation: isolated (any Actor)? = #isolation,
411
_ block: @escaping (Element) async -> Void
512
) -> AsyncMonitor {
613
AsyncMonitor(isolation: isolation, sequence: self, performing: block)
714
}
815

16+
/// Observes the elements yielded by this sequence and executes the given closure with each element the weakly-captured
17+
/// context object.
18+
///
19+
/// This method preserves the actor isolation of the caller by default when `isolation` is not specified.
20+
///
21+
/// - Parameters:
22+
/// - isolation: An optional actor isolation context to inherit. Defaults to `#isolation`, preserving the caller's actor isolation.
23+
/// - context: The object to capture weakly for use within the closure.
24+
/// - block: A closure that's executed with each yielded element, and the `context`.
925
func monitor<Context: AnyObject>(
1026
isolation: isolated (any Actor)? = #isolation,
1127
context: Context,

Sources/AsyncMonitor/NSObject+AsyncKVO.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ public import Foundation
33
extension KeyPath: @unchecked @retroactive Sendable where Value: Sendable {}
44

55
public extension NSObjectProtocol where Self: NSObject {
6+
/// Observes changes to the specified key path on the object and asynchronously yields each value. Values must be `Sendable`.
7+
///
8+
/// - Parameters:
9+
/// - keyPath: The key path to observe on this object. The value must be `Sendable`.
10+
/// - options: KVO options to use for observation. Defaults to an empty set.
11+
/// - changeHandler: A closure that's executed with each new value.
612
func values<Value: Sendable>(
713
for keyPath: KeyPath<Self, Value>,
814
options: NSKeyValueObservingOptions = [],

0 commit comments

Comments
 (0)