Don't restrict anything to the main actor

This commit is contained in:
Sami Samhuri 2025-04-26 11:05:19 -07:00
parent 9a7fbdf09d
commit b8eb878097
No known key found for this signature in database
4 changed files with 13 additions and 13 deletions

View file

@ -31,7 +31,7 @@ When you're integrating this into an app with Xcode then go to your project's Pa
When you're integrating this using SPM on its own then add this to the list of dependencies your Package.swift file:
```swift
.package(url: "https://github.com/samsonjs/AsyncMonitor.git", .upToNextMajor(from: "0.1.0"))
.package(url: "https://github.com/samsonjs/AsyncMonitor.git", .upToNextMajor(from: "0.1.1"))
```
and then add `"AsyncMonitor"` to the list of dependencies in your target as well.
@ -43,7 +43,7 @@ The simplest example uses a closure that receives the notification:
```swift
import AsyncMonitor
@MainActor class SimplestVersion {
class SimplestVersion {
let cancellable = NotificationCenter.default
.notifications(named: .NSCalendarDayChanged).map(\.name)
.monitor { _ in
@ -57,7 +57,7 @@ This example uses the context parameter to avoid reference cycles with `self`:
```swift
import AsyncMonitor
@MainActor class WithContext {
class WithContext {
var cancellables = Set<AnyAsyncCancellable>()
init() {

View file

@ -6,13 +6,13 @@ public extension NSObjectProtocol where Self: NSObject {
func values<Value: Sendable>(
for keyPath: KeyPath<Self, Value>,
options: NSKeyValueObservingOptions = [],
changeHandler: @escaping @MainActor (Value) -> Void
changeHandler: @escaping (Value) -> Void
) -> any AsyncCancellable {
let (stream, continuation) = AsyncStream<Value>.makeStream()
let token = self.observe(keyPath, options: options) { object, _ in
continuation.yield(object[keyPath: keyPath])
}
return stream.monitor { @MainActor value in
return stream.monitor { value in
_ = token // keep this alive
changeHandler(value)
}

View file

@ -2,7 +2,7 @@ import Foundation
import Testing
@testable import AsyncMonitor
@MainActor class AsyncMonitorTests {
class AsyncMonitorTests {
let center = NotificationCenter()
let name = Notification.Name("a random notification")
@ -24,18 +24,18 @@ import Testing
subject = center.notifications(named: name).map(\.name).monitor { receivedName in
Issue.record("Called for irrelevant notification \(receivedName)")
}
Task {
Task { [center] in
center.post(name: Notification.Name("something else"), object: nil)
}
try await Task.sleep(for: .milliseconds(10))
}
@Test func stopsCallingBlockWhenDeallocated() async throws {
@Test @MainActor func stopsCallingBlockWhenDeallocated() async throws {
subject = center.notifications(named: name).map(\.name).monitor { _ in
Issue.record("Called after deallocation")
}
Task {
Task { @MainActor in
subject = nil
center.post(name: name, object: nil)
}
@ -48,7 +48,7 @@ import Testing
private var cancellable: (any AsyncCancellable)?
@MainActor init(center: NotificationCenter, deinitHook: @escaping () -> Void) {
init(center: NotificationCenter, deinitHook: @escaping () -> Void) {
self.deinitHook = deinitHook
let name = Notification.Name("irrelevant name")
cancellable = center.notifications(named: name).map(\.name)
@ -78,7 +78,7 @@ import Testing
Issue.record("Called after context was deallocated")
}
context = nil
Task {
Task { [center, name] in
center.post(name: name, object: nil)
}
try await Task.sleep(for: .milliseconds(10))

View file

@ -1,7 +1,7 @@
import Foundation
@testable import AsyncMonitor
@MainActor class SimplestVersion {
class SimplestVersion {
let cancellable = NotificationCenter.default
.notifications(named: .NSCalendarDayChanged).map(\.name)
.monitor { _ in
@ -9,7 +9,7 @@ import Foundation
}
}
@MainActor class WithContext {
class WithContext {
var cancellables = Set<AnyAsyncCancellable>()
init() {