File tree Expand file tree Collapse file tree 5 files changed +91
-9
lines changed Expand file tree Collapse file tree 5 files changed +91
-9
lines changed Original file line number Diff line number Diff line change @@ -349,25 +349,54 @@ extension EntityStore {
349
349
extension EntityStore {
350
350
/// Removes an alias from the storage
351
351
public func removeAlias< T> ( named: AliasKey < T > ) {
352
- refAliases [ named] = nil
353
- logger? . didUnregisterAlias ( named)
352
+ transaction {
353
+ if let alias = refAliases [ named] {
354
+ do {
355
+ try alias. updateEntity ( AliasContainer ( key: named, content: nil ) , modifiedAt: nil )
356
+ logger? . didUnregisterAlias ( named)
357
+ }
358
+ catch {
359
+
360
+ }
361
+ }
362
+ }
354
363
}
355
364
356
365
/// Removes an alias from the storage
357
366
public func removeAlias< C: Collection > ( named: AliasKey < C > ) {
358
- refAliases [ named] = nil
359
- logger? . didUnregisterAlias ( named)
367
+ transaction {
368
+ if let alias = refAliases [ named] {
369
+ do {
370
+ try alias. updateEntity ( AliasContainer ( key: named, content: nil ) , modifiedAt: nil )
371
+ logger? . didUnregisterAlias ( named)
372
+ }
373
+ catch {
374
+
375
+ }
376
+ }
377
+ }
378
+
360
379
}
361
380
362
381
/// Removes all alias from identity map
363
382
public func removeAllAlias( ) {
364
- refAliases. removeAll ( )
383
+ transaction {
384
+ removeAliases ( )
385
+ }
365
386
}
366
387
367
388
/// Removes all alias AND all objects stored weakly. You should not need this method and rather use `removeAlias`.
368
389
/// But this can be useful if you fear retain cycles
369
390
public func removeAll( ) {
370
- refAliases. removeAll ( )
371
- storage. removeAll ( )
391
+ transaction {
392
+ removeAliases ( )
393
+ storage. removeAll ( )
394
+ }
395
+ }
396
+
397
+ private func removeAliases( ) {
398
+ for (_, node) in refAliases {
399
+ node. nullify ( )
400
+ }
372
401
}
373
402
}
Original file line number Diff line number Diff line change @@ -68,4 +68,18 @@ extension AliasContainer: CollectionIdentifiableKeyPathsEraser where T: MutableC
68
68
var erasedEntitiesKeyPaths : [ Any ] {
69
69
[ PartialIdentifiableKeyPath < Self > ( \. content) ]
70
70
}
71
- }
71
+ }
72
+
73
+ extension AliasContainer : Equatable where T: Equatable {
74
+
75
+ }
76
+
77
+ protocol Nullable {
78
+ func nullified( ) -> Self
79
+ }
80
+
81
+ extension AliasContainer : Nullable {
82
+ func nullified( ) -> AliasContainer < T > {
83
+ AliasContainer ( key: key, content: nil )
84
+ }
85
+ }
Original file line number Diff line number Diff line change 1
1
/// Keep a strong reference on each aliased node
2
- typealias AliasStorage = [ String : Any ]
2
+ typealias AliasStorage = [ String : AnyEntityNode ]
3
3
4
4
extension AliasStorage {
5
5
subscript< T> ( _ aliasKey: AliasKey < T > ) -> EntityNode < AliasContainer < T > > ? {
Original file line number Diff line number Diff line change @@ -4,6 +4,8 @@ import Combine
4
4
/// Typed erased protocol
5
5
protocol AnyEntityNode : AnyObject {
6
6
var value : Any { get }
7
+
8
+ func nullify( )
7
9
}
8
10
9
11
/// A graph node representing a entity of type `T` and its children. Anytime one of its children is updated the node
@@ -53,6 +55,12 @@ class EntityNode<T>: AnyEntityNode {
53
55
onChange ? ( self )
54
56
}
55
57
58
+ func nullify( ) {
59
+ if let value = ref. value as? Nullable {
60
+ try ? updateEntity ( value. nullified ( ) as! T , modifiedAt: nil )
61
+ }
62
+ }
63
+
56
64
func removeAllChildren( ) {
57
65
children = [ : ]
58
66
}
Original file line number Diff line number Diff line change @@ -424,6 +424,37 @@ extension EntityStoreTests {
424
424
}
425
425
}
426
426
427
+ // MARK: Remove
428
+ extension EntityStoreTests {
429
+ func test_removeAlias_itEnqueuesNilInRegistry( ) {
430
+ let registry = ObserverRegistryStub ( )
431
+ let store = EntityStore ( registry: registry)
432
+
433
+ _ = store. store ( entity: SingleNodeFixture ( id: 1 ) , named: . test)
434
+
435
+ registry. clearPendingChangesStub ( )
436
+
437
+ store. removeAlias ( named: . test)
438
+
439
+ XCTAssertTrue ( registry. hasPendingChange ( for: AliasContainer ( key: . test, content: nil ) ) )
440
+ }
441
+
442
+ func test_removeAllAlias_itEnqueuesNilForEachAlias( ) {
443
+ let registry = ObserverRegistryStub ( )
444
+ let store = EntityStore ( registry: registry)
445
+
446
+ _ = store. store ( entity: SingleNodeFixture ( id: 1 ) , named: . test)
447
+ _ = store. store ( entities: [ SingleNodeFixture ( id: 2 ) ] , named: . listOfNodes)
448
+
449
+ registry. clearPendingChangesStub ( )
450
+
451
+ store. removeAllAlias ( )
452
+
453
+ XCTAssertTrue ( registry. hasPendingChange ( for: AliasContainer ( key: . test, content: nil ) ) )
454
+ XCTAssertTrue ( registry. hasPendingChange ( for: AliasContainer ( key: . listOfNodes, content: nil ) ) )
455
+ }
456
+ }
457
+
427
458
private extension AliasKey where T == SingleNodeFixture {
428
459
static let test = AliasKey ( named: " test " )
429
460
}
You can’t perform that action at this time.
0 commit comments