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