Last active
August 10, 2022 06:49
-
-
Save michaeleisel/77b8efc9bedab1444dbb71a5915dbd15 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Note that this checker is always running, even when the app is in the background (where it doesn't matter if the main thread is blocked) | |
// You'll have to add more code if you don't want the checker to run while the app is in the background | |
final class ANRChecker { | |
private let ANRThreshold: CFTimeInterval = 5 | |
// This variable may be accessed from multiple threads at the same time. It won't cause issues, but if you want prevent the thread sanitizer from complaining, you can add locking around it or w/e | |
private lazy var lastResponseTime: CFTimeInterval = CACurrentMediaTime() | |
func beginChecking() { | |
updateLastResponseTime() | |
checkLastResponseTime() | |
} | |
private func updateLastResponseTime() { | |
lastResponseTime = CACurrentMediaTime() | |
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { | |
self.updateLastResponseTime() | |
} | |
} | |
private func checkLastResponseTime() { | |
crashIfDelayTooLarge() | |
DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now() + 1) { | |
self.checkLastResponseTime() | |
} | |
} | |
private func crashIfDelayTooLarge() { | |
let delay = CACurrentMediaTime() - self.lastResponseTime | |
if delay > self.ANRThreshold { | |
fatalError() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment