diff --git a/Sources/Swift/HangTracker.swift b/Sources/Swift/HangTracker.swift index 319cce75fbe..6cc8e5d0263 100644 --- a/Sources/Swift/HangTracker.swift +++ b/Sources/Swift/HangTracker.swift @@ -76,6 +76,9 @@ final class DefaultHangTracker { mainQueueState = .init() } + // It's safe to access mainQueueState here regardless of the thread + // because this is the only reference to `self` while + // it is being deallocated. deinit { guard let observer = mainQueueState.observer else { return diff --git a/Tests/SentryTests/Integrations/ANR/HangTrackerTests.swift b/Tests/SentryTests/Integrations/ANR/HangTrackerTests.swift index ca35e332ee1..f574dc6afda 100644 --- a/Tests/SentryTests/Integrations/ANR/HangTrackerTests.swift +++ b/Tests/SentryTests/Integrations/ANR/HangTrackerTests.swift @@ -208,6 +208,14 @@ final class HangTrackerTests: XCTestCase { sut = nil + // Allow the hang tracker's background thread to finish since it holds + // a strong reference while it is running + let expectation = XCTestExpectation() + queue.async { + expectation.fulfill() + } + wait(for: [expectation]) + XCTAssertNil(weakSut, "Expected observer to be deallocated") }