所以我是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
答案 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 */ })
我还没有对它进行测试,但可能是因为如果前一个动画在下一个动画开始时尚未完成,动画会重叠。