我正在尝试将图表添加到UITableView单元中,并且越来越遇到此问题:
2019-05-11 11:13:06.963721-0500 Prototype Settings[29076:5158720] *** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <Charts.ChartDataSet 0x600003f57480> for the key path "bounds" from <Charts.ChartDataSet 0x600003f57480> because it is not registered as an observer.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010622c6fb __exceptionPreprocess + 331
1 libobjc.A.dylib 0x0000000104e1aac5 objc_exception_throw + 48
2 CoreFoundation 0x000000010622c555 +[NSException raise:format:] + 197
3 Foundation 0x00000001048a05e1 -[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:] + 488
4 Foundation 0x00000001048a0a68 -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] + 84
5 Charts 0x000000010438e009 $s6Charts13ChartViewBaseCfD + 105
6 Prototype Settings 0x0000000103d24960 $s18Prototype_Settings9ChartCellC12initDataSetsyyF + 1808
7 Prototype Settings 0x0000000103d28c9f $s18Prototype_Settings14SessionDetailsC9tableView_12cellForRowAtSo07UITableF4CellCSo0kF0C_10Foundation9IndexPathVtF + 1295
8 Prototype Settings 0x0000000103d2a44b $s18Prototype_Settings14SessionDetailsC9tableView_12cellForRowAtSo07UITableF4CellCSo0kF0C_10Foundation9IndexPathVtFTo + 155
9 UIKitCore 0x000000010eb8b62c -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 764
10 UIKitCore 0x000000010eb8bb65 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 73
11 UIKitCore 0x000000010eb53d20 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2870
12 UIKitCore 0x000000010eb73e37 -[UITableView layoutSubviews] + 165
13 UIKitCore 0x000000010ee209c1 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1417
14 QuartzCore 0x0000000106f35eae -[CALayer layoutSublayers] + 173
15 QuartzCore 0x0000000106f3ab88 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 396
16 QuartzCore 0x0000000106f46ee4 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 72
17 QuartzCore 0x0000000106eb63aa _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 328
18 QuartzCore 0x0000000106eed584 _ZN2CA11Transaction6commitEv + 608
19 UIKitCore 0x000000010e97a3a4 _afterCACommitHandler + 245
20 CoreFoundation 0x00000001061930f7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
21 CoreFoundation 0x000000010618d5be __CFRunLoopDoObservers + 430
22 CoreFoundation 0x000000010618dc31 __CFRunLoopRun + 1505
23 CoreFoundation 0x000000010618d302 CFRunLoopRunSpecific + 626
24 GraphicsServices 0x000000010ae312fe GSEventRunModal + 65
25 UIKitCore 0x000000010e952ba2 UIApplicationMain + 140
26 Prototype Settings 0x0000000103d2bd0b main + 75
27 libdyld.dylib 0x0000000108568541 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
这似乎仅在我在UITableView单元格中使用此图表时才会发生。我假设它与UITableView的工作方式有关,但是我似乎无法使其正常工作。
我的代码
import UIKit
import Charts
class ChartCell : UITableViewCell
{
@IBOutlet weak var chart: LineChartView!
var dataSet1: LineChartDataSet?
var dataSet2: LineChartDataSet?
var data: LineChartData?
func initDataSets()
{
dataSet1 = LineChartDataSet([
// First four must be 0 for design.
ChartDataEntry(x: 0, y: 0),
ChartDataEntry(x: 1, y: 0),
ChartDataEntry(x: 2, y: 0),
ChartDataEntry(x: 3, y: 6),
ChartDataEntry(x: 4, y: 9),
ChartDataEntry(x: 5, y: 5),
ChartDataEntry(x: 6, y: 8),
ChartDataEntry(x: 7, y: 18),
ChartDataEntry(x: 8, y: 14),
ChartDataEntry(x: 9, y: 12),
// Last three must be 0 for design
ChartDataEntry(x: 10, y: 0),
ChartDataEntry(x: 11, y: 0)
])
dataSet2 = LineChartDataSet(values: [
// First four must be 0 for design.
ChartDataEntry(x: 0, y: 0),
ChartDataEntry(x: 1, y: 0),
ChartDataEntry(x: 2, y: 0),
ChartDataEntry(x: 3, y: 6),
ChartDataEntry(x: 4, y: 9),
ChartDataEntry(x: 5, y: 5),
ChartDataEntry(x: 6, y: 8),
ChartDataEntry(x: 7, y: 18),
ChartDataEntry(x: 8, y: 14),
ChartDataEntry(x: 9, y: 12),
// Last three must be 0 for design
ChartDataEntry(x: 10, y: 0),
ChartDataEntry(x: 11, y: 0)
],
label: ""
)
dataSet1?.drawIconsEnabled = false
dataSet1?.drawCirclesEnabled = false
dataSet1?.drawCircleHoleEnabled = false
dataSet1?.drawValuesEnabled = false
dataSet1?.lineCapType = .round
dataSet1?.colors = [rgbToUiColor(rgb: 0xFF0000)]
dataSet1?.highlightEnabled = false
dataSet1?.lineWidth = 2;
dataSet1?.mode = .horizontalBezier
dataSet2?.drawIconsEnabled = false
dataSet2?.drawCirclesEnabled = false
dataSet2?.drawCircleHoleEnabled = false
dataSet2?.drawValuesEnabled = false
dataSet2?.lineCapType = .round
dataSet2?.highlightEnabled = false
dataSet2?.lineWidth = 2;
dataSet2?.mode = .horizontalBezier
dataSet2?.colors = [rgbToUiColor(rgb: 0x00FF00)]
data = LineChartData(dataSets: [dataSet1!, dataSet2!])
}
func initializeChart()
{
chart.backgroundColor = UIColor(white: 1, alpha: 0)
chart.marker = nil;
chart.xAxis.drawAxisLineEnabled = false
chart.xAxis.drawGridLinesEnabled = false
chart.xAxis.drawLabelsEnabled = false
chart.drawBordersEnabled = false;
chart.layoutMargins = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
chart.leftAxis.drawAxisLineEnabled = false
chart.leftAxis.drawGridLinesEnabled = false
chart.leftAxis.drawLabelsEnabled = false
chart.xAxis.enabled = false
chart.leftAxis.enabled = false
chart.rightAxis.enabled = false
chart.drawBordersEnabled = false
chart.minOffset = 0
chart.rightAxis.drawAxisLineEnabled = false
chart.rightAxis.drawGridLinesEnabled = false
chart.rightAxis.drawLabelsEnabled = false
chart.legend.enabled = false;
chart.data = data!
//chart.animate(xAxisDuration: 1.0, yAxisDuration: 0)
}
func rgbToUiColor(rgb: Int) -> UIColor {
return UIColor(
red: CGFloat((rgb >> 16) & 0xFF) / 255.0,
green: CGFloat((rgb >> 8) & 0xFF) / 255.0,
blue: CGFloat(rgb & 0xFF) / 255.0,
alpha: 1.0
);
}
}
然后我用以下内容创建单元格:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
. . .
let cell = self.tableView.dequeueReusableCell(withIdentifier: "NetworkStatsGraphCell", for: indexPath) as! ChartCell
cell.initDataSets()
cell.initializeChart()
return cell
. . .
这似乎是在 ChartViewBase.swift
此处发生的:
deinit
{
self.removeObserver(self, forKeyPath: "bounds")
self.removeObserver(self, forKeyPath: "frame")
}
ChartView本身未能从自己的观察者中删除,这是在 ChartViewBase.swift 中添加的:
internal func initialize()
{
. . .
self.addObserver(self, forKeyPath: "bounds", options: .new, context: nil)
self.addObserver(self, forKeyPath: "frame", options: .new, context: nil)
}