@@ -112,7 +112,7 @@ public final class Signal<Value, Error: Swift.Error> {
112
112
private var hasDeinitialized : Bool
113
113
114
114
fileprivate init ( _ generator: ( Observer ) -> Disposable ? ) {
115
- state = . alive( AliveState ( ) )
115
+ state = . alive( AliveState ( observers : Bag ( ) ) )
116
116
117
117
updateLock = Lock . make ( )
118
118
sendLock = Lock . make ( )
@@ -225,7 +225,9 @@ public final class Signal<Value, Error: Swift.Error> {
225
225
updateLock. lock ( )
226
226
227
227
if case let . alive( state) = state {
228
- token = state. observers. insert ( observer)
228
+ var observers = state. observers
229
+ token = observers. insert ( observer)
230
+ self . state = . alive( AliveState ( observers: observers) )
229
231
}
230
232
231
233
updateLock. unlock ( )
@@ -250,7 +252,7 @@ public final class Signal<Value, Error: Swift.Error> {
250
252
if case let . alive( state) = state {
251
253
var observers = state. observers
252
254
let observer = observers. remove ( using: token)
253
- state . observers = observers
255
+ self . state = . alive ( AliveState ( observers: observers ) )
254
256
255
257
var result = OperationResult . none
256
258
@@ -450,13 +452,14 @@ public final class Signal<Value, Error: Swift.Error> {
450
452
private final class AliveState {
451
453
/// The observers of the `Signal`.
452
454
///
453
- /// - note: Since `Bag` is a copy-on-write collection, writes can be done safety
454
- /// as long as `updateLock` is acquired.
455
- fileprivate var observers : Bag < Observer >
455
+ /// - important: `observer` should not be mutated directly given the layout of
456
+ /// `Bag`. Copy the bag, and replace the current `AliveState` with
457
+ /// a new one created with the bag instead.
458
+ fileprivate let observers : Bag < Observer >
456
459
457
460
/// Create an alive state.
458
- init ( ) {
459
- self . observers = Bag ( )
461
+ init ( observers : Bag < Observer > ) {
462
+ self . observers = observers
460
463
}
461
464
}
462
465
0 commit comments