无法识别的选择器发送到实例 _UIAlertControllerAlertPresentationController

Unrecognized selector sent to instance _UIAlertControllerAlertPresentationController

我的 iOS 应用程序中有几个 errors 实时场景。我无法理解 Core Foundation 上的这个特定错误,它影响了我的应用程序中的多个用户。流程没有中断我的任何项目文件,我不确定是什么导致了这次崩溃。

附上 crashlytics 日志。任何建议或帮助都会有很大帮助,thanx。

CoreFoundation _CF_forwarding_prep_0

Fatal Exception: NSInvalidArgumentException -[_UIAlertControllerAlertPresentationController adaptivePresentationController]: unrecognized selector sent to instance 0x133e29870

Fatal Exception: NSInvalidArgumentException
0  CoreFoundation                 0x18ff391b8 __exceptionPreprocess
1  libobjc.A.dylib                0x18e97055c objc_exception_throw
2  CoreFoundation                 0x18ff40268 __methodDescriptionForSelector
3  CoreFoundation                 0x18ff3d270 ___forwarding___
4  CoreFoundation                 0x18fe3680c _CF_forwarding_prep_0
5  UIKit                          0x19689708c -[UISearchController _searchPresentationController]
6  UIKit                          0x19648f8cc -[_UISearchControllerTransplantSearchBarAnimator animateTransition:]
7  UIKit                          0x19613d464 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke
8  UIKit                          0x19607ffdc _runAfterCACommitDeferredBlocks
9  UIKit                          0x196071d50 _cleanUpAfterCAFlushAndRunDeferredBlocks
10 UIKit                          0x195de10b4 _afterCACommitHandler
11 CoreFoundation                 0x18fee60c0 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
12 CoreFoundation                 0x18fee3cf0 __CFRunLoopDoObservers
13 CoreFoundation                 0x18fee4180 __CFRunLoopRun
14 CoreFoundation                 0x18fe122b8 CFRunLoopRunSpecific
15 GraphicsServices               0x1918c6198 GSEventRunModal
16 UIKit                          0x195e597fc -[UIApplication _run]
17 UIKit                          0x195e54534 UIApplicationMain
18 Levo                           0x1000c1c30 main (AppDelegate.swift:22)
19 libdispatch.dylib              0x18edf55b8 (Missing)
func showErrorView(errorType: ErrorType, retryClickDelegate: ErrorViewRetryClickDelegate?) {
    var message = ""
    switch errorType {
    case .INTERNET:
        message = "Your internet connection does not seem to be working. Kindly ensure that you are connected to the internet and try again"
        break
    case .INVALID_DATA:
        message = "Something went wrong. Please try again!"
        break
    case .JSON_PARSING:
        message = "Something went wrong. Please try again!"
        break
    case .UNAUTHORIZED:
        self.showInformativeAlert("Logged Out", message: "Looks like you have been logged out. Please login in again!", completion: nil)
        self.switchStoryboard(Storyboard.SIGNIN)
        return
    default:
        message = "Something went wrong. Please try again!"
    }

    let errorAlert = UIAlertController(title: "Error", message: message, preferredStyle: .Alert)
    if let retryClickDelegate = retryClickDelegate {
        errorAlert.addAction(UIAlertAction(title: "Try again", style: UIAlertActionStyle.Default, handler: { (action) in
            retryClickDelegate.onErrorRetryClicked(errorType)
            errorAlert.dismissViewControllerAnimated(true, completion: nil)
        }))
    }
    errorAlert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))

    if (isTopViewController) {
        self.presentViewController(errorAlert, animated: true, completion: nil)
    }
}

func showInformativeAlert(title: String?, message: String?,completion : (() -> Void)?) {
    let informativeAlert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
    informativeAlert.addAction(UIAlertAction(title: "Got it!", style: UIAlertActionStyle.Default, handler: { (action) in
        informativeAlert.dismissViewControllerAnimated(true, completion: nil)
        completion?()
    }))
    self.presentViewController(informativeAlert, animated: true, completion: nil)
}

public var isTopViewController: Bool {
    if self.navigationController != nil {
        return self.navigationController?.visibleViewController === self
    } else if self.tabBarController != nil {
        return self.tabBarController?.selectedViewController == self && self.presentedViewController == nil
    } else {
        return self.presentedViewController == nil && self.isVisible
    }
}

我认为问题是您没有正确使用完成处理程序,因此同时出现和消失了一个警报。例如,而不是:

    informativeAlert.dismissViewControllerAnimated(true, completion: nil)
    completion?()

你应该使用

    informativeAlert.dismissViewControllerAnimated(true, completion: completion)

此外,如果视图控制器动画正在进行中,isTopViewController 的实现很容易失败。

例如,如果您调用 showErrorView 两次,两次调用的 isTopViewController 可能会 true 并且会同时出现两个警报,从而使您的应用程序崩溃。