@@ -400,11 +400,24 @@ class HeartbeatStorageTests: XCTestCase {
400400 }
401401
402402 func testForMemoryLeakInInstanceManager( ) {
403+ // This unchecked Sendable class is used to avoid passing a non-sendable
404+ // type '[WeakContainer<HeartbeatStorage>]' to a `@Sendable` closure
405+ // (`DispatchQueue.global().async { ... }`).
406+ final class WeakRefs : @unchecked Sendable {
407+ private( set) var weakRefs : [ WeakContainer < HeartbeatStorage > ] = [ ]
408+ // Lock is used to synchronize `weakRefs` during concurrent access.
409+ private let weakRefsLock = NSLock ( )
410+
411+ func append( _ weakRef: WeakContainer < HeartbeatStorage > ) {
412+ weakRefsLock. withLock {
413+ weakRefs. append ( weakRef)
414+ }
415+ }
416+ }
417+
403418 // Given
404419 let id = " testID "
405- var weakRefs : [ WeakContainer < HeartbeatStorage > ] = [ ]
406- // Lock is used to synchronize `weakRefs` during concurrent access.
407- let weakRefsLock = NSLock ( )
420+ let weakRefs = WeakRefs ( )
408421
409422 // When
410423 // Simulate concurrent access. This will help expose race conditions that could cause a crash.
@@ -413,9 +426,7 @@ class HeartbeatStorageTests: XCTestCase {
413426 group. enter ( )
414427 DispatchQueue . global ( ) . async {
415428 let instance = HeartbeatStorage . getInstance ( id: id)
416- weakRefsLock. withLock {
417- weakRefs. append ( WeakContainer ( object: instance) )
418- }
429+ weakRefs. append ( WeakContainer ( object: instance) )
419430 group. leave ( )
420431 }
421432 }
@@ -424,7 +435,7 @@ class HeartbeatStorageTests: XCTestCase {
424435 // Then
425436 // The `weakRefs` array's references should all be nil; otherwise, something is being
426437 // unexpectedly strongly retained.
427- for weakRef in weakRefs {
438+ for weakRef in weakRefs. weakRefs {
428439 XCTAssertNil ( weakRef. object, " Potential memory leak detected. " )
429440 }
430441 }
0 commit comments