Непринятая ошибка/обработка исключений в Swift
Я знаю, что в Cocoa есть UncaughtExceptionHandler, но я ищу то же самое для Swift. т.е. всякий раз, когда в приложении есть какая-либо ошибка/исключение, которое не попадает в локальную сеть из-за какой-либо ошибки, оно должно пузыриться до самого объекта приложения верхнего уровня, где я должен умело обрабатывать его и соответствующим образом реагировать на пользователя.
У Android есть это. У Flex есть это. У Java есть это. Удивление, почему Swift не хватает этой ключевой функции.
Ответы
Ответ 1
У Swift нет механизма для исключения всех произвольных исключений во время выполнения. Причины объясняются в
на форуме быстрых пользователей. Выдержка:
Свифт сделал сознательный выбор, чтобы не включать исключения, выброшенные через произвольные стековые кадры, не потому, что это было технически невозможно, а потому, что его дизайнеры считали, что издержки слишком высоки.
Проблема заключается в следующем: если часть кода рано или поздно выходит из-за ошибки, она должна быть записана для обработки этого раннего выхода. В противном случае это приведет к неправильной работе - не удастся освободить память, не удастся закрыть файловые дескрипторы/сокеты/соединения с базой данных/что угодно, не выпустить блокировки и т.д. На языке, таком как Java, для написания действительно безопасного кода требуется нелепое количество try/finally блоки. Вот почему никто этого не делает. Они делают суждения о том, какие исключения они видят и какие ресурсы опасны для утечки, и только защищают свой код от этих конкретных ожидаемых условий. Затем происходит что-то непредвиденное, и их программа ломается.
Это даже хуже на языке с подсчетом ссылок, таком как Swift, потому что правильно балансировать подсчет ссылок при наличии исключений в основном требует, чтобы каждая функция включала неявный блок finally, чтобы сбалансировать все показатели сохранения. Это означает, что компилятор должен генерировать много дополнительного кода во избежание того, что какой-либо вызов или другое генерирует исключение. Подавляющее большинство этого кода никогда, никогда не используется, но оно должно быть там, раздувание процесса.
Из-за этих проблем Свифт решил не поддерживать традиционные исключения; вместо этого он позволяет вам допускать ошибки в специально выделенных областях кода. Но, как следствие, это означает, что если что-то пойдет не так в коде, который не может бросить, все, что он действительно может сделать, чтобы предотвратить катастрофу, - это крах. И в настоящее время единственное, с чем вы можете столкнуться - это весь процесс.
Для получения дополнительной информации см.
Ответ 2
Это код, который я использую для регистрации всех исключений/ошибок. 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
}
Ответ 3
Я не могу комментировать, потому что у меня меньше 50 репутации. Я хочу объяснить этот вопрос @Jack
пусть х = [1]; print (x [5]) НЕ пойман, есть ли шанс с быстрой обработкой ошибок?
Это может поймать быстрое крушение!
В быстром проекте , "Eidt Scheme" → выберите "Run debug" → close "Debug исполняемый файл"
Тогда попробуйте еще раз.
Ответ 4
enter code here
импорт UIKit import CoreData
class ViewController: UIViewController {
@IBOutlet weak var lgnusername: UITextField!
@IBOutlet weak var lgnpassword: UITextField!
var result = 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")
}
}
}