diff --git a/Sources/Defaults/Defaults.swift b/Sources/Defaults/Defaults.swift index 6dc9a25..d0cd040 100644 --- a/Sources/Defaults/Defaults.swift +++ b/Sources/Defaults/Defaults.swift @@ -285,7 +285,7 @@ extension Defaults { continuation.onTermination = { _ in // `invalidate()` should be thread-safe, but it is not in practice. - DispatchQueue.main.async { + Task { @MainActor in observation.invalidate() } } @@ -334,7 +334,7 @@ extension Defaults { continuation.onTermination = { _ in // `invalidate()` should be thread-safe, but it is not in practice. - DispatchQueue.main.async { + Task { @MainActor in for observation in immutableObservations { observation.invalidate() } @@ -378,7 +378,7 @@ extension Defaults { continuation.onTermination = { _ in // `invalidate()` should be thread-safe, but it is not in practice. - DispatchQueue.main.async { + Task { @MainActor in for observation in observations { observation.invalidate() } diff --git a/Sources/Defaults/SwiftUI.swift b/Sources/Defaults/SwiftUI.swift index 3c9c2a0..13c26af 100644 --- a/Sources/Defaults/SwiftUI.swift +++ b/Sources/Defaults/SwiftUI.swift @@ -75,8 +75,9 @@ Access stored values from SwiftUI. This is similar to `@AppStorage` but it accepts a ``Defaults/Key`` and many more types. */ +@MainActor @propertyWrapper -public struct Default: DynamicProperty { +public struct Default: @preconcurrency DynamicProperty { @_documentation(visibility: private) public typealias Publisher = AnyPublisher, Never> @@ -254,8 +255,10 @@ extension Defaults.Toggle { } } +@MainActor @propertyWrapper private struct ViewStorage: DynamicProperty { + @MainActor private final class ValueBox { var value: Value diff --git a/Tests/DefaultsTests/DefaultsSwiftUITests.swift b/Tests/DefaultsTests/DefaultsSwiftUITests.swift index 1aba762..def6ae2 100644 --- a/Tests/DefaultsTests/DefaultsSwiftUITests.swift +++ b/Tests/DefaultsTests/DefaultsSwiftUITests.swift @@ -41,6 +41,7 @@ final class DefaultsSwiftUITests { Defaults.removeAll(suite: suite_) } + @MainActor @Test func testSwiftUIObserve() { let view = ContentView()