我无法理解我收到的UIKit崩溃报告:
有没有办法找出导致这个问题的代码行:
Crashed: com.apple.main-thread 0 UIKit 0x195694264 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 444 1 UIKit 0x1955d0950 _runAfterCACommitDeferredBlocks + 292 2 UIKit 0x1955c29ec _cleanUpAfterCAFlushAndRunDeferredBlocks + 528 3 UIKit 0x195336648 _afterCACommitHandler + 132 4 CoreFoundation 0x18f1c09a8 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32 5 CoreFoundation 0x18f1be630 __CFRunLoopDoObservers + 372 6 CoreFoundation 0x18f1bea7c __CFRunLoopRun + 956 7 CoreFoundation 0x18f0eeda4 CFRunLoopRunSpecific + 424 8 GraphicsServices 0x190b58074 GSEventRunModal + 100 9 UIKit 0x1953a9058 UIApplicationMain + 208 10 FlexConnect 0x1001b48c8 main (AppDelegate.swift:20) 11 libdyld.dylib 0x18e0fd59c start + 4
错误本身是:
崩溃:com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000010
编辑:
根据下面的答案,我想知道是否建议使用:
func topMostController() -> UIViewController { var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController! while (topController.presentedViewController != nil) { topController = topController.presentedViewController! } return topController }
并且总是打电话
let topVC = topMostController().dismiss(animated: true,completion: nil)
在我的应用程序的任何地方,我目前有self.dismiss(动画:真,完成:零)?
这是一个必要的检查或如何确定self.dismiss有问题的地方?
一些样本解雇:
@IBAction func returnToDash(_ sender: UIButton) { self.dismiss(animated: true,completion: nil) } let pending = UIAlertController(title: "\n\n\n\(title)",message: nil,preferredStyle: .alert) displayActivityAlertWithCompletion2(ViewController: self,pending: pending){_ in Helper_StatusCheck.doSync(_cleanSync: false){ Prefs.is_Syncing = false DispatchQueue.main.async { pending.dismiss(animated: true){ Toast(text: "Upload sync completed").show() self.dismiss(animated: true,completion: nil) } } } }
displayActivityAlertWithCompletion2的位置如下:
public func displayActivityAlertWithCompletion2(ViewController: UIViewController,pending: UIAlertController,completionHandler: @escaping ()->()) { //let pending = UIAlertController(title: "\n\n\n"+title,preferredStyle: .alert) //create an activity indicator let indicator = UIActivityIndicatorView(frame: pending.view.bounds) indicator.autoresizingMask = [.flexibleWidth,.flexibleHeight] indicator.color = UIColor(rgba: Palette.loadingColour) //add the activity indicator as a subview of the alert controller's view pending.view.addSubview(indicator) indicator.isUserInteractionEnabled = false // required otherwise if there buttons in the UIAlertController you will not be able to press them indicator.startAnimating() ViewController.present(pending,animated: true,completion: completionHandler) }
编辑2:
我的应用程序中的一些示例popover方法:
@IBAction func search(_ sender: UIButton) { if let popView = UIStoryboard(name: "AssetCommon",bundle: nil).instantiateViewController(withIdentifier: "searchPop") as? searchPopVC { popView.delegate = self popView.modalPresentationStyle = .popover; popView.popoverPresentationController?.delegate = self popView.popoverPresentationController?.barButtonItem = searchButton popView.popoverPresentationController?.permittedArrowDirections = .any popView.preferredContentSize = CGSize(width: 300,height: 70) self.present(popView,completion: nil) } }
并搜索pop:
class searchPopVC: UIViewController { @IBOutlet weak var searchBar: UISearchBar! weak var delegate: SearchPopDelegate? override func viewDidLoad() { super.viewDidLoad() searchBar.delegate = self; } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } @IBAction func performSearch(_ sender: UIButton) { let term = searchBar.text ?? ""; delegate?.performSearch(with: term) self.dismiss(animated: true,completion: nil); } } extension searchPopVC: UISearchBarDelegate { func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { let term = searchBar.text ?? ""; delegate?.performSearch(with: term); self.dismiss(animated: true,completion: nil) } }
您将无法从此崩溃中找到代码行.但是,当您在动画完成之前从视图层次结构中删除用于调用dismiss(animated:completion :)的视图控制器时,会发生此崩溃.
根据代码的设置方式,您可以尝试请求更高的视图控制器来调用解雇.另一种解决方案可能是将视图控制器保留在属性中,直到您确定完成它为止.
编辑:1/5/18
在回应这些注释时,这里是一个示例,说明如何为记录事件和解散的视图控制器创建一个函数.
extension UIViewController { func dismissAndLog(animated: Bool,completion: (() -> ())? = nil) { // Here are two examples of how your view controller can be identified. // let id = title let id = String(describing: type(of: self)) CLSLogv("Dismissed View Controller: %@",getVaList([id])) dismiss(animated: animated,completion: completion) } }
我并不完全熟悉Crashlytics或他们的API,因此如果此日志记录给您带来问题,您可以查看这些链接.
> https://docs.fabric.io/apple/crashlytics/enhanced-reports.html#custom-logging-in-swift
> How to use Crashlytics logging in Swift?
另外我不知道他们是如何向你提供数据的,所以我无法向你解释解析它的最佳方法.然而,时间戳肯定可以成功地用作最终解决方案.您还可以尝试通过电子邮件发送他们的支持,询问将这些日志映射到崩溃的最佳方法.