Bug
WatchConnectivitySession.storedDelegate (WatchConnectivitySession.swift, the NSLock-guarded backing store behind the delegate property) is a strong reference. Delegate patterns conventionally hold weak references; here, any observer that owns the session and registers itself as delegate forms a cycle:
observer → session (strong let) → storedDelegate (strong) → observer
Concretely, SundialKitStream's ConnectivityObserver does exactly this in its initializer, making the observer un-deinit-able (companion issue: brightdigit/SundialKitStream#17). The existing #warning("replace with a property wrapper or internal actor") on the lock is adjacent tech debt in the same property.
Fix direction
Store the delegate weakly (weak var storedDelegate: (any ConnectivitySessionDelegate & AnyObject)? — the protocol already requires AnyObject? if not, constrain it), keeping the lock or replacing it per the existing #warning.
Bug
WatchConnectivitySession.storedDelegate(WatchConnectivitySession.swift, the NSLock-guarded backing store behind thedelegateproperty) is a strong reference. Delegate patterns conventionally hold weak references; here, any observer that owns the session and registers itself as delegate forms a cycle:observer → session (strong
let) → storedDelegate (strong) → observerConcretely, SundialKitStream's
ConnectivityObserverdoes exactly this in its initializer, making the observer un-deinit-able (companion issue: brightdigit/SundialKitStream#17). The existing#warning("replace with a property wrapper or internal actor")on the lock is adjacent tech debt in the same property.Fix direction
Store the delegate weakly (
weak var storedDelegate: (any ConnectivitySessionDelegate & AnyObject)?— the protocol already requiresAnyObject? if not, constrain it), keeping the lock or replacing it per the existing #warning.