iOS 计时器函数堆损坏

iOS Timer function heap corruption

所以我是 iOS 的新手,我正在尝试使用一个带有定时器的视图控制器来定期更新 UI。我看到的问题是堆损坏,更具体地说是 EXC_BAD_ACCESS KERN_INVALID_ADDRESS 由 objc_retain 调用引起的错误。

这个错误发生在几个地方,但都在我的 Timer 函数中和调用堆栈的更高层 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION 在每种情况下都被调用。

我一定是遗漏了一个参考或者没有正确发布一些东西,这是代码

func scheduleTimer() {
    timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(self.timerFunc), userInfo: nil, repeats: true)
}

func timerFunc() {
    if let gps = sdlService?.getLatestLocation() {
        let clCoor = CLLocationCoordinate2D(locStruct: gps)
        self.updateLatestDriverIcon(gps: gps, coor: clCoor)
        if isRecording {
            self.addNextPathPoint(coor: clCoor)
        }
        latestCoor = clCoor
    }
}

func updateLatestDriverIcon(gps: LocationStruct, coor: CLLocationCoordinate2D) {
    if latestCoor == nil {
        car = MarkerAnnotation(coordinate: coor, title: carMarker)
        mapView.addAnnotation(car!)
        latestCoor = coor
        mapView.centerOnLatestGPS(animated: false)
        markerView.rotation = MathUtils.wrap(gps.bearing, min: 0, max: 360)
    } else if coor.isDifferent(to: latestCoor!) {
        if isMapFollowingCar {
            mapView.centerOnLatestGPS(animated: false)
        }
        car!.coordinate = coor
        markerView.rotation = MathUtils.wrap(gps.bearing, min: 0, max: 360)
    }
}

现在这个计时器函数正在引用我的视图控制器的属性,以及一个嵌套函数 (updateLatestDriverIcon)。我已经看到 mapView.centerOnLatestGPS() 函数崩溃,并且 markerView.rotation 调用堆栈中的多个位置都具有上面列出的相同错误代码。 我在这里错过了什么?

编辑: 这是来自 crashlytics 的堆栈跟踪。我正在使用通过外部附件触发的事件,因此我可以连接到调试器: Stack Trace

所以在追踪了几周之后,我们发现这是由于 UIView 上的动画引起的。不完全确定为什么它会在它发生的地方抛出错误,如果有人知道为什么那会非常有帮助!以下是有关架构的更多信息:

我们有一个屏幕以大约 10HZ 的频率更新 UI,并由使用上述代码的计时器驱动。动画是在 UIView 子类上完成的,该子类是在渲染到位图上下文中的主线程中完成的。这是在 ~30Hz 下完成的。

动画代码:

UIView.animate(
        withDuration: self.animationDuration,
        animations: { self.currentGearValue = actualGearValue },
        completion: { (isComplete) in  /* not sure we need this yet */ })

我没有测试过,但可能是因为如果前一个动画在下一个动画开始时还没有完成,那么动画就会重叠。