I cannot get my head around the crash I've received. In particular I'd be interested to find out what does <Arg[0] = Dead>
mean? Is the sender
in didUpdate()
somehow dead?
This is the report:
Hardware Model: iPhone11,2
Code Type: arm64
Parent Process: [1]
Date/Time: 2021-01-23T06:20:16.999Z
Launch Time: 2021-01-22T18:46:28Z
OS Version: iPhone OS 14.3 (18C66)
Exception Type: SIGTRAP
Exception Codes: TRAP_BRKPT at 0x100361d60
Crashed Thread: 0
Thread 0 Crashed:
0 App-Name 0x0000000100361d60 function signature specialization <Arg[0] = Dead> of App_Name.SessionViewController.didUpdate(_: App_Name.ElapsedTimeSource, interval: Swift.Double) -> () (SessionViewController.swift:0)
1 App-Name 0x000000010065953c App_Name.ElapsedTimeSource.(update in _B9C509359F1F9AD84C977E95030096FE)() -> () (ElapsedTimeSource.swift:57)
2 App-Name 0x00000001006593d4 App_Name.ElapsedTimeSource.start() -> () (ElapsedTimeSource.swift:48)
3 App-Name 0x000000010036111c App_Name.SessionViewController.(displayInSession in _1C441B89ACF9824195FFFFDA0A95A40F)(App_Name.Session) -> () (SessionViewController.swift:112)
The ElapsedTimeSource
and the delegate in full:
protocol ElapsedTimeSourceDelegate: AnyObject {
func didUpdate(_ sender: ElapsedTimeSource, interval: TimeInterval)
}
// Use on the main thread
class ElapsedTimeSource {
var startDate: Date {
didSet {
if startDate != oldValue {
elapsed = Date().timeIntervalSince(startDate)
}
}
}
weak private var delegate: ElapsedTimeSourceDelegate?
private var elapsed: TimeInterval = 0
private var isRunning = false
private let interval: TimeInterval
init(startDate: Date, delegate: ElapsedTimeSourceDelegate, interval: TimeInterval = 1) {
self.startDate = startDate
self.delegate = delegate
self.interval = interval
}
func start() {
if isRunning { return }
isRunning = true
elapsed = Date().timeIntervalSince(startDate)
update() // *** Line 48 ***
}
func stop() {
isRunning = false
}
private func update() {
delegate?.didUpdate(self, interval: elapsed) // *** Line 57 ***
let actualElapsed = Date().timeIntervalSince(startDate)
let correction = elapsed - actualElapsed
DispatchQueue.main.asyncAfter(deadline: .now() + interval + correction) { [weak self] in
guard let self = self else { return }
self.elapsed += self.interval
if self.isRunning {
self.update()
}
}
}
}
And the relevant bits of the SessionViewController
:
class SessionViewController: UIViewController {
private var elapsedTimeSource: ElapsedTimeSource?
private func displayInSession(_ session: Session) {
if let elapsedTimeSource = elapsedTimeSource {
elapsedTimeSource.startDate = session.startTime
elapsedTimeSource.start()
} else {
elapsedTimeSource = ElapsedTimeSource(startDate: session.startTime, delegate: self)
elapsedTimeSource?.start() // *** Line 112 ***
}
}
}
extension SessionViewController: ElapsedTimeSourceDelegate {
func didUpdate(_ sender: ElapsedTimeSource, interval: TimeInterval) {
let formatter = DateComponentsFormatter()
if interval < 3600 {
// Force showing minutes even when time is less than 1 min
formatter.allowedUnits = [.second, .minute]
} else {
formatter.allowedUnits = [.second, .minute, .hour]
}
formatter.zeroFormattingBehavior = .pad
let elapsed = formatter.string(from: interval) ?? ""
sessionElapsedTimeLabel.text = elapsed
}
}
I would be grateful for any learned input really!
question from:
https://stackoverflow.com/questions/65858071/crash-with-function-signature-specialization-arg0-dead 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…