崩溃仅在 iOS13 之后引起,我无法重现

Crash only caused since iOS13 which I can't reproduce

Crashlytics 一直在记录这个我似乎无法重现的崩溃。我查看了代码,但找不到任何可能导致此崩溃的内容。

奇怪的是它在 iOS13 发布后才出现。所有崩溃都发生在安装了 iOS13 的设备上。在 iOS13 之前,这种崩溃从未发生过。这段特殊的代码已经存在两年多了。

谁能想出是什么原因造成的?

提前致谢。

Crashed: com.apple.main-thread
0  Spotted by                     0x104eaf2c0 partial apply for closure #1 in CitiesListViewController.tableSections.didset + 35 (CitiesListViewController.swift:35)
1  Spotted by                     0x104ee8508 thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)
2  libdispatch.dylib              0x1b48b1610 _dispatch_call_block_and_release + 24
3  libdispatch.dylib              0x1b48b2184 _dispatch_client_callout + 16
4  libdispatch.dylib              0x1b489535c _dispatch_main_queue_callback_4CF$VARIANT$armv81 + 996
5  CoreFoundation                 0x1b4b623c4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
6  CoreFoundation                 0x1b4b5d3b8 __CFRunLoopRun + 2004
7  CoreFoundation                 0x1b4b5c8bc CFRunLoopRunSpecific + 464
8  GraphicsServices               0x1be9c8328 GSEventRunModal + 104
9  UIKitCore                      0x1b8bf26d4 UIApplicationMain + 1936
10 Spotted by                     0x104e95c00 main + 21 (SBLAppDelegate.swift:21)
11 libdyld.dylib                  0x1b49e7460 start + 4

这是我的代码(第 35 行是 self.tableView.reloadData()):

typealias TableData = [SectionData]
typealias SectionData = [String: [Any]]

private var tableSections = TableData() {
    didSet {
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}

数据源代码:

func setupData() {
    let sortPurchasedCitiesByAlpha: (CityID, CityID) -> Bool = { (cityId1, cityId2) -> Bool in
        guard
            let city1 = CitiesManager.shared.city(withId: cityId1),
            let city2 = CitiesManager.shared.city(withId: cityId2)
            else { assertionFailure("missing cities?"); return false }
        return city1.name.lowercased() <= city2.name.lowercased()
    }
    var sections = TableData()
    // reverse to show most recent purchase first
    let allPurchased = Array(CitiesManager.shared.purchasedCityIds())
    var purchased: [CityID] = []
    let lastUsedCityId = Defaults[.lastUsedCity]
    if let lastUsedCityId = lastUsedCityId {
        // put last used first
        let rest = Array(allPurchased.removing(lastUsedCityId))
        let restSorted = rest.sorted(by: sortPurchasedCitiesByAlpha)
        if allPurchased.contains(lastUsedCityId) { // may have been deleted
            purchased.append(lastUsedCityId)
        }
        purchased.append(contentsOf: restSorted)
    } else {
        purchased = allPurchased.sorted(by: sortPurchasedCitiesByAlpha)
    }
    installedSectionPresent = !purchased.isEmpty
    if installedSectionPresent {
        sections.append(["Installed": purchased])
    }
    let continents = CitiesManager.shared.allContinentsOfNotPurchasedCities()
    continents.forEach { continent in
        let cityIds = CitiesManager.shared.cityIdsNotPurchased(forContinent: continent)
        sections.append([continent: cityIds])
    }
    tableSections = sections
}

可能会在创建整个视图层次结构之前调用 setter。

尝试

private var tableSections = TableData() {
    didSet {
        DispatchQueue.main.async {
            self.tableView?.reloadData()
        }
    }
}