Проблема
При написании юнит-тестов и макете NSTimer
Я вижу
Exception: EXC_BAD_ACCESS (code=1, address=0x8)
внутри
swift_isUniquelyReferenced_nonNull_native
Ситуация возникает при доступе массив invalidateInvocations
(внутри func invalidate()
) здесь.
class TimerMock: Timer {
/// Timer callback type
typealias TimerCallback = ((Timer) -> Void)
/// The latest used timer mock accessible to control
static var currentTimer: TimerMock!
/// The block to be invoked on a firing
private var block: TimerCallback!
/// Invalidation invocations (will contain the fireInvocation indices)
var invalidateInvocations: [Int] = []
/// Fire invocation count
var fireInvocations: Int = 0
/// Main function to control a timer fire
override open func fire() {
block(self)
fireInvocations += 1
}
/// Hook into invalidation
override open func invalidate() {
invalidateInvocations.append(fireInvocations)
}
/// Hook into the timer configuration
override open class func scheduledTimer(withTimeInterval interval: TimeInterval,
repeats: Bool,
block: @escaping TimerCallback) -> Timer {
// return timer mock
TimerMock.currentTimer = TimerMock()
TimerMock.currentTimer.block = block
return TimerMock.currentTimer
}
}
Интересно, что если я поменяю invalidateInvocations
на обычный Int
, он будет доступен без сбоев.
Поскольку доступ к этой переменной приводит к EXC_BAD_ACCESS
Я бы предположил, что массив уже освобожден, но я не вижу, как это может произойти.
Демонстрация
Вы можно увидеть полный пример запуска и сбоя в этом репозитории (ветвь demo/crash
)
https://github.com/nomad5modules/ArcProgressViewIOS/tree/demo/crash
Просто выполните модульные тесты и увидите, что они дают сбой.
Вопрос
Что здесь происходит? Я наблюдал cra sh внутри swift_isUniquelyReferenced_nonNull_native
уже в других проектах, и я хотел бы полностью понять причину этой неудачи! Так как происходит процесс, чтобы выяснить, что здесь не так? И как это исправить?
Автономный проект воспроизведения
https://drive.google.com/file/d/1fMGhgpmBRG6hzpaiTM9lO_zCZwNhwIpx/view?usp=sharing