2017-08-14 42 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 */ }) 

我沒有測試它,但它可能是因爲,如果前一個不是由一個動畫被啓動的時間完成了動畫重疊。