尝试显示带有消息的 UIAlertController 时应用程序崩溃:由于未捕获的异常“NSInvalidArgumentException”而终止应用程序

Posted

技术标签:

【中文标题】尝试显示带有消息的 UIAlertController 时应用程序崩溃:由于未捕获的异常“NSInvalidArgumentException”而终止应用程序【英文标题】:App crashes when attempting to display UIAlertController with message: Terminating app due to uncaught exception 'NSInvalidArgumentException' 【发布时间】:2018-09-26 23:04:26 【问题描述】:

此警报控制器已初始化:

let alertVC2 = PMAlertController(title: "Need to always enable location authorization", description: "Go to Settings -> App -> Location. Then select 'Always'.", image: UIImage(named: "Location"), style: .alert)

ViewDidLoad() 内部,动作被添加到alertVC2

alertVC2.addAction(PMAlertAction(title: "OK", style: .default, action:  () in

            print("Capture action OK")
            self.alertVC2.dismiss(animated: true, completion: nil)
        ))

 alertVC2.addTextField  (textField) in
            textField?.placeholder = "Location..."
        

另外,在viewDidLoad() 中,添加了这段代码的 sn-p,这将允许我在应用程序在后台休眠后再次激活时运行名为 willResignActive 的函数:

 NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: UIApplication.didBecomeActiveNotification, object: nil)

这是一个在应用再次激活时运行的函数:

@objc func willResignActive(_ notification: Notification) 
        print("activated")

      check()
    

check() 函数中,alertVC2 (AlertController) 将被调用,并且警报控制器将显示在屏幕上。当我通过使应用程序恢复运行来使应用程序恢复生机时,会显示警报控制器。但是,当我第二次退出应用程序并再次返回时,它不会显示alertVC2。当我第三次这样做时,应用程序崩溃了。

这里是check()函数的简要介绍:

func check() 

    if CLLocationManager.authorizationStatus() == .notDetermined || CLLocationManager.authorizationStatus() == .authorizedWhenInUse || CLLocationManager.authorizationStatus() == .denied || CLLocationManager.authorizationStatus() == .restricted 

    locationManager.requestWhenInUseAuthorization()
        locationManager.requestAlwaysAuthorization()

        if CLLocationManager.authorizationStatus() != .authorizedAlways 

        print("Need to always authorize location for me")

        self.present(alertVC2, animated: true, completion: nil)

        
    

    if CLLocationManager.authorizationStatus() == .authorizedAlways 

        locationManager.startUpdatingLocation()

    



这是我在第三次尝试应用崩溃时收到的错误消息:

由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'应用程序试图呈现 模态的主动控制器

我必须做些什么来防止它崩溃并继续发布警报控制器?

【问题讨论】:

ViewController 的类型是您的第一个控制器吗?你打电话给self.present(...) 您为什么不通过didBecomeActive 通知这样做? 和can you dismiss the currently visible view controller 在您提出该警报之前? @YuryImashev 这只是 UIViewController。 我认为您需要在再次展示之前关闭最后展示的 AlertConrtoller 即 alertVC2。请使用断点并调试您的代码。可能是您的 check() 函数调用不止一次 【参考方案1】:

听起来您正在尝试多次显示警报控制器。如果你在调用 self.present 的那一行放一个断点,它会命中多少次?

如果我的猜测是正确的,那么简单的方法是检查视图当前是否正在显示任何内容,如果是,请跳过显示警报。可能是这样的:

if CLLocationManager.authorizationStatus() != .authorizedAlways 
    print("Need to always authorize location for me")
    if self.presentedViewController == nil 
        self.present(alertVC2, animated: true, completion: nil)
    


或者可能是这样的:

if CLLocationManager.authorizationStatus() != .authorizedAlways 
    print("Need to always authorize location for me")
    if !alertVC2.isBeingPresented  // make sure we're not already presenting this alert to the user
        self.present(alertVC2, animated: true, completion: nil)
    


【讨论】:

以上是关于尝试显示带有消息的 UIAlertController 时应用程序崩溃:由于未捕获的异常“NSInvalidArgumentException”而终止应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何在屏幕上显示带有附加的数据的验证错误消息?

闪亮的不显示带有 HTML/JSON 错误消息的表格

带有 Chakra UI 的 React-hook-form 未在 NextJS 中显示验证错误消息

带有位置服务的 wkwebview

显示带有延迟标题和消息的 actionSheet 样式的警报

呈现警报控制器时 UIPopOverController 缩小