我很奇怪,很难再现iOS 9上发生的崩溃.问题是如何解决这个或什么导致这个异常
正如您所看到的,跟踪不包含我的代码,并且在应用启动时会发生崩溃.
Last Exception Backtrace:
0 CoreFoundation 0x0000000180a49900 __exceptionPreprocess + 124
1 libobjc.A.dylib 0x00000001800b7f80 objc_exception_throw + 52
2 CoreFoundation 0x0000000180a497d0 +[NSException raise:format:arguments:] + 104
3 Foundation 0x00000001813bca08 -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 84
4 UIKit 0x00000001859f9f34 _prepareForCAFlush + 252
5 UIKit 0x00000001859ff4f0 _beforeCACommitHandler + 12
6 CoreFoundation 0x0000000180a00588 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 28
7 CoreFoundation 0x00000001809fe32c __CFRunLoopDoObservers + 368
8 CoreFoundation 0x00000001809fe75c __CFRunLoopRun + 924
9 CoreFoundation 0x000000018092d680 CFRunLoopRunSpecific + 380
10 GraphicsServices 0x0000000181e3c088 GSEventRunModal + 176
11 UIKit 0x00000001857a4d90 UIApplicationMain + 200
12 MyAppName 0x000000010009d200 main (main.m:14)
13 ??? 0x00000001804ce8b8 0x0 + 0
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x00000001805ec140 __pthread_kill + 8
1 libsystem_pthread.dylib 0x00000001806b4ef8 pthread_kill + 108
2 libsystem_c.dylib 0x000000018055ddac abort + 136
3 MyAppName 0x0000000100805bcc uncaught_exception_handler + 28
4 CoreFoundation 0x0000000180a49c88 __handleUncaughtException + 648
5 libobjc.A.dylib 0x00000001800b823c _objc_terminate() + 108
6 libc++abi.dylib 0x00000001800aaf44 std::__terminate(void (*)()) + 12
7 libc++abi.dylib 0x00000001800aab10 __cxa_rethrow + 140
8 libobjc.A.dylib 0x00000001800b8120 objc_exception_rethrow + 40
9 CoreFoundation 0x000000018092d728 CFRunLoopRunSpecific + 548
10 GraphicsServices 0x0000000181e3c088 GSEventRunModal + 176
11 UIKit 0x00000001857a4d90 UIApplicationMain + 200
12 MyAppName 0x000000010009d200 main (main.m:14)
13 ??? 0x00000001804ce8b8 0x0 + 0
Run Code Online (Sandbox Code Playgroud)
我也遇到过同样的崩溃,与reason: 'unexpected start state'.
这是造成它的原因:
我在 tableView 中有一个单元格,其中包含一个标题设置为电子邮件地址的按钮。当您按下按钮时,我需要它来打开邮件应用程序。
当它打开邮件应用程序时,我的具有 tableView 的 viewController 正在重新加载traitCollectionDidChange. 这tableView.reloadData()导致了崩溃,很可能是因为应用程序正在活动状态和后台之间转换。
这是我所做的:
class NewsDetailsFooterCell: UITableViewCell {
//MARK: - Callbacks
var sendEmail: ((_ emailUrl: URL) -> ())?
//MARK: - IBActions
@IBAction func openAuthorEmail(_ sender: UIButton) {
guard let emailAddress = sender.titleLabel?.text, let url = URL(string: "mailto:\(emailAddress)") else { return }
guard UIApplication.shared.canOpenURL(url) else { return }
self.sendEmail?(url)
}
}
Run Code Online (Sandbox Code Playgroud)
cellForRowAt使用了回调并修改了一个局部变量,该变量负责阻止 tableView 的 reloadData 函数traitCollectionDidChange:func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let newsFooterCell = tableView.dequeueReusableCell(withIdentifier: "NewsDetailsFooterCell") as! NewsDetailsFooterCell
//other cell setup
newsFooterCell.sendEmail = { [weak self] emailUrl in
self?.viewModel.canReloadTable = false //this is the variable which I need to modify here
UIApplication.shared.open(emailUrl, options: [:], completionHandler: nil)
}
return newsFooterCell
}
Run Code Online (Sandbox Code Playgroud)
traitCollectionDidChange仅当变量为 true 时,我才重新加载表的数据canReloadTable:override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if #available(iOS 12.0, *) {
//using this delegate method to trigger data reload to adapt to Dark/Light modes
guard viewModel.canReloadTable else { return }
tableView.reloadData()
}
}
Run Code Online (Sandbox Code Playgroud)
canReloadTable回trueinviewDidAppear override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
viewModel.canReloadTable = true
}
Run Code Online (Sandbox Code Playgroud)
我希望这个答案可以帮助其他人,或者至少提供有关在哪里调查潜在问题的线索,因为错误本身根本没有描述性,我花了大约 1-2 个小时调查它并提出解决方案。