Swift中未捕获的错误/异常处理

时间:2016-08-03 08:06:46

标签: swift uncaughtexceptionhandler

我知道Cocoa中有一个UncaughtExceptionHandler,但我正在为Swift寻找同样的东西。即每当应用程序中由于任何错误而未在本地捕获任何错误/异常时,它应该一直冒泡到顶级应用程序对象,在那里我应该能够优雅地处理它并适当地响应用户。

Android有它。 Flex有它。 Java有它。想知道Swift为什么缺少这个关键功能。

3 个答案:

答案 0 :(得分:11)

Swift没有机制来捕获所有任意运行时异常。 原因在

中解释

在swift-users论坛中。提取物:

  斯威夫特有意识地选择不包括抛出的异常   任意堆栈帧不是因为技术上不可能,而是   因为它的设计师认为成本过高。

     

问题在于:如果一段代码要提前退出,因为   一个错误,必须编写它来处理提前退出。除此以外   它会行为错误 - 无法释放内存,无法关闭文件   处理/套接字/数据库连接/无论如何,无法释放锁,   在像Java这样的语言中,编写真正的异常安全代码   需要一定数量的try / finally块。这就是为什么   没有人这样做。他们判断他们是哪些例外   可能会看到和哪些资源泄漏是危险的,而且只是   保护他们的代码免受那些特定的预期条件然后   一些无法预料的事情发生了,他们的计划破裂了。

     

在像Swift这样的引用计数语言中,情况更糟   在存在异常的情况下正确平衡引用计数   基本上要求每个函数都包含一个隐含的finally块   平衡所有保留计数。这意味着编译器必须这样做   有些人打电话或者有机会产生大量的额外代码   另一个抛出异常。绝大多数代码永远不会,   曾经使用过,但它必须在那里,使这个过程膨胀。

     

由于这些问题,Swift选择不支持传统   例外情况;相反,它只允许你输入错误   特别标记的代码区域。但作为推论,这意味着,   如果在无法抛出的代码中出现问题,那么一切都可以   真的要防止灾难崩溃。而目前,唯一的   你可以崩溃的是整个过程。

有关详细信息,请参阅

答案 1 :(得分:9)

这是我用来记录所有异常/错误的代码。 Log.error(with:)是一个自定义函数,我存储堆栈跟踪以及其他信息。 Thread.callStackSymbols是一个字符串数组,表示堆栈跟踪。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool {

    NSSetUncaughtExceptionHandler { exception in
        Log.error(with: Thread.callStackSymbols)
    }

    signal(SIGABRT) { _ in
        Log.error(with: Thread.callStackSymbols)
    }

    signal(SIGILL) { _ in
        Log.error(with: Thread.callStackSymbols)
    }

    signal(SIGSEGV) { _ in
        Log.error(with: Thread.callStackSymbols)
    }

    signal(SIGFPE) { _ in
        Log.error(with: Thread.callStackSymbols)
    }

    signal(SIGBUS) { _ in
        Log.error(with: Thread.callStackSymbols)
    }

    signal(SIGPIPE) { _ in
        Log.error(with: Thread.callStackSymbols)
    }

    return true
}

答案 2 :(得分:-4)

enter code here

导入UIKit 导入CoreData

ViewController类:UIViewController {

@IBOutlet weak var lgnusername: UITextField!

@IBOutlet weak var lgnpassword: UITextField!

var结果= NSArray()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}



@IBAction func loginaction(_ sender: Any)
{

    let app = UIApplication.shared.delegate as! AppDelegate

    let context = app.persistentContainer.viewContext



    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Login")
    let searchString = self.lgnusername.text
    let searcghstring2 = self.lgnpassword.text
    request.predicate = NSPredicate (format: "username == %@", searchString!)
    do
    {
        let result = try context.fetch(request)
        if result.count > 0
        {
            let   n = (result[0] as AnyObject).value(forKey: "username") as! String
            let p = (result[0] as AnyObject).value(forKey: "userpassword") as! String
             print("p,n",n,p)


            if (searchString == n && searcghstring2 == p)
            {
                let UserDetailsVc = self.storyboard?.instantiateViewController(withIdentifier: "userViewController") as! userViewController
                //UserDetailsVc.myStringValue = lgnusername.text
                self.navigationController?.pushViewController(UserDetailsVc, animated: true)
            }
            else if (searchString == n || searcghstring2 == p)
            {
                // print("password incorrect ")
                let alertController1 = UIAlertController (title: "no user found ", message: "password incorrect ", preferredStyle: UIAlertControllerStyle.alert)
                alertController1.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                present(alertController1, animated: true, completion: nil)
            }
        }
        else
        {
            let alertController1 = UIAlertController (title: "no user found ", message: "invalid username ", preferredStyle: UIAlertControllerStyle.alert)
            alertController1.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            present(alertController1, animated: true, completion: nil)
            print("no user found")
        }
    }
    catch
    {
        print("error")
    }
}

}