2017-08-14 118 views
0

因此,我是iOS新手,正在尝试使用具有定时更新UI的计时器的视图控制器。我看到的问题是我正在获取堆损坏,更具体地说是由objc_retain调用引起的EXC_BAD_ACCESS KERN_INVALID_ADDRESS错误。iOS定时器功能堆损坏

此错误是在几个地方,但都在我的定时器功能和更高的调用堆栈__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

您是否在此视图控制器释放之前/之前使计时器无效? – Paulw11

+0

无论何时导航离开此页面,我都使其无效,但这不会影响我看到的问题,因为第一次运行应用程序时出现崩溃 – Cityzensnips

+0

您能否显示'centerOnLatestGPS'的代码?那是发生这次事故的地方。 – Paulw11

回答

0

因此,经过几个星期的跟踪,我们发现这是由于UIView上的动画。不完全确定它为什么会抛出错误,如果有人知道为什么这会非常有帮助!这里有一些关于架构的更多信息:

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

动画代码:

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

我没有测试它,但它可能是因为,如果前一个不是由一个动画被启动的时间完成了动画重叠。