iOS Timer函数堆损坏

时间:2017-08-14 00:46:53

标签: ios swift timer mapkit heap-corruption

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

这个错误发生在几个地方,但都在我的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

1 个答案:

答案 0 :(得分:0)

因此,经过几周的追踪,我们发现这是由于UIView上的动画。如果有人知道为什么那会非常有帮助的话,不完全确定它为什么会抛出错误呢?以下是有关架构的更多信息:

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

动画代码:

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

我还没有对它进行测试,但可能是因为如果前一个动画在下一个动画开始时尚未完成,动画会重叠。