I'm trying to understand a crash report I've got from crashlytics which looks like this:
Crashed: com.apple.main-thread
0 App 0x104076730 RaceViewController.tableView(_:cellForRowAt:) + 4369164080 (<compiler-generated>:4369164080)
1 App 0x104076800 @objc RaceViewController.tableView(_:cellForRowAt:) + 4369164288 (<compiler-generated>:4369164288)
2 UIKitCore 0x1b6039b24 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 736
3 UIKitCore 0x1b6007870 -[UITableView _updateVisibleCellsNow:] + 2500
4 UIKitCore 0x1b60245d8 -[UITableView layoutSubviews] + 160
5 UIKitCore 0x1b62f785c -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2144
6 QuartzCore 0x1b888a724 -[CALayer layoutSublayers] + 284
7 QuartzCore 0x1b889087c CA::Layer::layout_if_needed(CA::Transaction*) + 468
8 QuartzCore 0x1b889b3c0 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 140
9 QuartzCore 0x1b87e3f1c CA::Context::commit_transaction(CA::Transaction*, double) + 296
10 QuartzCore 0x1b880d8bc CA::Transaction::commit() + 676
11 UIKitCore 0x1b5e6ca30 _afterCACommitHandler + 140
12 CoreFoundation 0x1b1d1a06c __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
13 CoreFoundation 0x1b1d14f60 __CFRunLoopDoObservers + 420
14 CoreFoundation 0x1b1d153dc __CFRunLoopRun + 968
15 CoreFoundation 0x1b1d14ce8 CFRunLoopRunSpecific + 424
16 GraphicsServices 0x1bbe5f38c GSEventRunModal + 160
17 UIKitCore 0x1b5e43444 UIApplicationMain + 1932
18 App 0x104066764 main + 13 (Race.swift:13)
19 libdyld.dylib 0x1b1b9c8f0 start + 4
I can see points to two places, RaceViewController.tableView(_:cellForRowAt:)
& Race.swift:13
.
Lets look at those two places in the code:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let day = self.days[indexPath.section]
var totalIndex = 0
var raceIndex = 0
for selectedRace in racesByDay[day]! {
if (totalIndex == indexPath.row) {
let cell = tableView.dequeueReusableCell(withIdentifier: "raceCell")! as! RaceCell
cell.delegate = self
cell.populate(event: self.event!, selectableRace: self.racesByDay[day]![raceIndex])
return cell
}
if selectedRace.opened {
if (indexPath.row <= totalIndex + selectedRace.race.classes.count) {
let cell = tableView.dequeueReusableCell(withIdentifier: "competitorClassCell")! as! CompetitorClassCell
cell.delegate = self
cell.populate(competitorClass: selectedRace.race.classes[indexPath.row - totalIndex - 1], selectableRace: selectedRace)
return cell
}
totalIndex += selectedRace.race.classes.count
} else {
totalIndex += 1
}
raceIndex += 1
}
return tableView.dequeueReusableCell(withIdentifier: "raceCell")!
}
and Race.swift:
import UIKit
import SwiftyJSON
class Race {
var id: String <-- this is line 13
var name: String
var viewerUrl: String
var trackingStartTime: Date
var trackingEndTime: Date
var expectedStartDate: String
var raceStarttime: Date?
var mapPublicationTime: Date?
var initialized: Bool
...
}
How can I understand where the crash happened with this information? I'm not able to reproduce the crash.
Wat you are looking at is referred to as the stack. It's basically the path that was being executed when the crash occurred.
The top of the stack (at index 0) is where the crash really happened and is usually a good place to start.
It's important to figure out the exact line where the crash happened. Sometimes it can be hard to figure out the real line, here it seems to refer to line 4369164080, which doesn't make much sense. Did you upload all the DSYM Files ?
Another hint can usually be found in the Keys
tab of Firebase/Crashlytics. See if there is a field named crash_info_entry_0
, this can tell you more about the crash.
In the code sample you posted, I see quite some force unwraps happening, so my first guess would be that one of those turned out to be nil. Perhaps because of a race condition.
I have the same crush. To be on the safe side I would add the following lines:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard self.days.count > indexPath.section else {
print("Crash is here")
return UITableViewCell()
}
let day = self.days[indexPath.section]
var totalIndex = 0
var raceIndex = 0
...
}
Sometimes when you are re-using the tableView and/or changing it's dataSource, tableView may attempt to layout before your dataSource is filled with data. The reason could be some heavy operations or async process. So it's better to check index before subscripting array
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.