11import Combine
22import Foundation
33
4- #if swift(>=6.0)
5- @MainActor
6- #endif
74/// A property wrapper that stores and observes values in `UserDefaults` with support for encoding and decoding.
85///
96/// `Defaults` synchronizes with `UserDefaults`, enabling automatic storage, retrieval, and observation
@@ -93,16 +90,7 @@ public final class Defaults<Value: Codable & Equatable> {
9390 self . decoderGenerator = decoder ?? { . init( ) }
9491
9592 self . defaultsObserver = . init( key: key, userDefaults: userDefaults)
96- defaultsObserver. updateHandler = { [ weak self] _ in
97- self ? . syncMain ( )
98- }
99-
100- // sometimes KVO is not working
101- self . notificationToken = NotificationCenter . default. addObserver ( forName: UserDefaults . didChangeNotification,
102- object: userDefaults,
103- queue: . main) { [ weak self] _ in
104- self ? . syncMain ( )
105- }
93+ subscribe ( )
10694 }
10795
10896 deinit {
@@ -111,6 +99,24 @@ public final class Defaults<Value: Codable & Equatable> {
11199 }
112100 }
113101
102+ private func subscribe( ) {
103+ // swiftformat:disable:next all
104+ let unsafeSync = UnsafeSendable ( { [ weak self] in
105+ self ? . syncMain ( )
106+ } )
107+
108+ defaultsObserver. updateHandler = { [ unsafeSync] _ in
109+ unsafeSync. value ( )
110+ }
111+
112+ // sometimes KVO is not working
113+ notificationToken = NotificationCenter . default. addObserver ( forName: UserDefaults . didChangeNotification,
114+ object: userDefaults,
115+ queue: . main) { [ unsafeSync] _ in
116+ unsafeSync. value ( )
117+ }
118+ }
119+
114120 private nonisolated func syncMain( ) {
115121 assert ( Thread . isMainThread, " Should be used only in main thread " )
116122
@@ -197,10 +203,6 @@ public extension Defaults where Value: ExpressibleByDictionaryLiteral, Value.Key
197203 }
198204}
199205
200- #if swift(>=6.0)
201- extension Defaults : @unchecked Sendable { }
202- #endif
203-
204206private final class DefaultsObserver : NSObject {
205207 private let userDefaults : UserDefaults
206208 private let key : String
@@ -223,7 +225,7 @@ private final class DefaultsObserver: NSObject {
223225 userDefaults. removeObserver ( self , forKeyPath: key, context: nil )
224226 }
225227
226- override public func observeValue( forKeyPath keyPath: String ? , of object: Any ? , change: [ NSKeyValueChangeKey : Any ] ? , context: UnsafeMutableRawPointer ? ) {
228+ override func observeValue( forKeyPath keyPath: String ? , of object: Any ? , change: [ NSKeyValueChangeKey : Any ] ? , context: UnsafeMutableRawPointer ? ) {
227229 guard let change, keyPath == key else {
228230 return
229231 }
@@ -239,20 +241,18 @@ private final class DefaultsObserver: NSObject {
239241 }
240242}
241243
242- #if swift(>=6.0)
243- extension DefaultsObserver : @unchecked Sendable { }
244-
245- private struct UnsafeSendable < T> : @unchecked Sendable {
244+ private struct UnsafeSendable < T> {
246245 let value : T
247246}
248- #else
249- struct UnsafeSendable < T> {
250- let value : T
251- }
252- #endif
253247
254248extension UnsafeSendable {
255249 init ( _ value: T ) {
256250 self . value = value
257251 }
258252}
253+
254+ #if swift(>=6.0)
255+ extension Defaults : @unchecked Sendable { }
256+ extension DefaultsObserver : @unchecked Sendable { }
257+ extension UnsafeSendable : @unchecked Sendable { }
258+ #endif
0 commit comments