Я не слишком много читал о Swift, но заметил одну вещь: исключений нет. Так как же они обрабатывают ошибки в Swift? Кто-нибудь нашел что-нибудь связанное с обработкой ошибок?
swift
error-handling
PEKO
источник
источник
Ответы:
Свифт 2 и 3
Ситуация немного изменилась в Swift 2, поскольку появился новый механизм обработки ошибок, который несколько больше похож на исключения, но отличается в деталях.
1. Указание на возможность ошибки
Если функция / метод хочет указать, что она может выдать ошибку, она должна содержать
throws
ключевое слово, подобное этомуПримечание: не существует спецификации для типа ошибки, которую функция может выдать. В этом объявлении просто говорится, что функция может генерировать экземпляр любого типа, реализующий ErrorType, или не генерирует вообще.
2. Вызывающая функция, которая может выдавать ошибки
Для вызова функции вам нужно использовать ключевое слово try, например:
в этой строке обычно должен присутствовать блок do-catch, подобный этому
Примечание: предложение catch использует все мощные функции сопоставления с образцом Swift, поэтому вы здесь очень гибки.
Вы можете решить распространить ошибку, если вы вызываете функцию выброса из функции, которая сама помечена
throws
ключевым словом:Кроме того, вы можете вызвать функцию броска, используя
try?
:Таким образом, вы получите либо возвращаемое значение, либо nil, если произошла какая-либо ошибка. Используя этот способ, вы не получите объект ошибки.
Это означает, что вы также можете сочетать
try?
с полезными утверждениями, такими как:или
Наконец, вы можете решить, что знаете, что ошибка на самом деле не возникнет (например, потому что вы уже проверили предварительные условия), и использовать
try!
ключевое слово:Если функция фактически выдает ошибку, то вы получите ошибку времени выполнения в вашем приложении, и приложение прекратит работу.
3. Бросать ошибку
Чтобы сгенерировать ошибку, используйте ключевое слово throw, как это
Вы можете бросить все, что соответствует
ErrorType
протоколу. Для началаNSError
соответствует этому протоколу, но вы, вероятно, хотели бы использовать enum-based,ErrorType
который позволяет группировать несколько связанных ошибок, возможно, с дополнительными фрагментами данных, напримерОсновные различия между новым механизмом ошибок Swift 2 и 3 и исключениями в стиле Java / C # / C ++ заключаются в следующем:
do-catch
+try
+defer
против традиционногоtry-catch-finally
синтаксиса.do-catch
блок не будет перехватывать исключение NSEx и наоборот, для этого вы должны использовать ObjC.NSError
соглашениями метода Какао о возвращении либоfalse
(дляBool
возврата функций), либоnil
(дляAnyObject
возврата функций) и передачиNSErrorPointer
с подробностями ошибки.В качестве дополнительного синтетического сахара для облегчения обработки ошибок, есть еще две концепции
defer
ключевого слова), которые позволяют достичь того же эффекта, что и блоки finally в Java / C # / etcguard
ключевого слова), который позволяет писать немного меньше кода if / else, чем в обычном коде проверки / сигнализации ошибокСвифт 1
Ошибки во время выполнения:
Как Leandros предлагает для обработки ошибок времени выполнения (таких как проблемы с сетевым подключением, анализ данных, открытие файла и т. Д.), Вы должны использовать их так же,
NSError
как в ObjC, потому что Foundation, AppKit, UIKit и т. Д. Сообщают о своих ошибках таким образом. Так что это скорее элементарная вещь, чем языковая.Другой частый шаблон, который используется, это блоки успеха / отказа разделителя, как в AFNetworking:
По-прежнему в блоке
NSError
с ошибками часто принимают экземпляр, описывающий ошибку.Ошибки программиста:
Для ошибок программиста (например, за пределами доступа к элементу массива, неверных аргументов, переданных на вызов функции и т. Д.) Вы использовали исключения в ObjC. Язык Swift, похоже, не имеет никакой языковой поддержки для исключений (например
throw
,catch
ключевое слово etc). Тем не менее, как видно из документации, он работает в той же среде выполнения, что и ObjC, и поэтому вы все еще можете выполнитьNSExceptions
следующее:Вы просто не можете поймать их в чистом Swift, хотя вы можете выбрать перехват исключений в коде ObjC.
Вопрос заключается в том, следует ли вам выдавать исключения для ошибок программиста, или, скорее, использовать утверждения, как Apple предлагает в руководстве по языку.
источник
fatalError(...)
такая же , как хорошо.Обновление 9 июня 2015 - Очень важно
Swift 2.0 поставляется с
try
,throw
иcatch
ключевыми словами и наиболее интересным является:Отрывок из: Apple Inc. «Использование Swift с какао и Objective-C (пререлиз Swift 2)». интерактивные книги.
Пример: (из книги)
Эквивалент по быстрому будет:
Выдает ошибку:
Будет автоматически передан вызывающей стороне:
Из книг Apple, языка программирования Swift, кажется, что ошибки должны обрабатываться с помощью enum.
Вот пример из книги.
От: Apple Inc. «Язык программирования Swift». интерактивные книги. https://itun.es/br/jEUH0.l
Обновить
Из новостных книг Apple «Использование Swift с какао и Objective-C». Исключения во время выполнения не возникают при использовании быстрых языков, поэтому у вас нет try-catch. Вместо этого вы используете опциональную цепочку .
Вот отрывок из книги:
Выдержка из: Apple Inc. «Использование Swift с какао и Objective-C». интерактивные книги. https://itun.es/br/1u3-0.l
И книги также побуждают вас использовать образец ошибки какао из Objective-C (NSError Object)
Выдержка из: Apple Inc. «Использование Swift с какао и Objective-C». интерактивные книги. https://itun.es/br/1u3-0.l
источник
В Swift нет исключений, похожих на подход Objective-C.
В процессе разработки вы можете использовать
assert
для обнаружения любых ошибок, которые могут появиться и которые необходимо исправить перед началом работы.Классический
NSError
подход не меняется, вы отправляетеNSErrorPointer
, который заполняется.Краткий пример:
источник
f();g();
становитсяf(&err);if(err) return;g(&err);if(err) return;
на первый месяц, потом просто становитсяf(nil);g(nil);hopeToGetHereAlive();
Рекомендуемый «быстрый путь»:
Однако я предпочитаю попробовать / поймать, так как мне легче следовать, потому что в конце он переносит обработку ошибок в отдельный блок, такое расположение иногда называют «Золотым путем». К счастью, вы можете сделать это с помощью замыканий:
Также легко добавить средство повтора:
Список для TryBool:
Вы можете написать аналогичный класс для тестирования дополнительного возвращаемого значения вместо значения Bool:
В версии TryOptional применяется необязательный тип возвращаемого значения, что облегчает последующее программирование, например, «Swift Way:
Использование TryOptional:
Обратите внимание на автоматическое развертывание.
источник
Изменить: хотя этот ответ работает, он немного больше, чем Objective-C транслитерируется в Swift. Это было сделано устаревшими изменениями в Swift 2.0. Ответ Гильерма Торреса Кастро, приведенный выше, является очень хорошим введением в предпочтительный способ обработки ошибок в Swift. СДН
Потребовалось немного разобраться, но я думаю, что подозревал это. Это кажется некрасивым. Ничего, кроме тонкой кожи над версией Objective-C.
Вызов функции с параметром NSError ...
Написание функции, которая принимает параметр ошибки ...
источник
Базовая оболочка вокруг цели C, которая дает вам функцию try catch. https://github.com/williamFalcon/SwiftTryCatch
Используйте как:
источник
Это обновленный ответ для Swift 2.0. Я с нетерпением жду многофункциональную модель обработки ошибок, как в Java. Наконец, они объявили хорошие новости. Вот
например:
источник
Как сказал Гильерме Торрес Кастро, в Swift 2.0,
try
,catch
,do
могут быть использованы при программировании.Например, в CoreData выборки метод данных, вместо того , чтобы положить в
&error
качестве параметра вmanagedContext.executeFetchRequest(fetchRequest, error: &error)
, теперь нужно использовать только использовать ,managedContext.executeFetchRequest(fetchRequest)
а затем обработать ошибку сtry
,catch
( Apple , Document Link )Если вы уже загрузили бета-версию xcode7. Попробуйте выполнить поиск ошибок в Документациях и Справочнике по API и выберите первый показывающий результат, он дает общее представление о том, что можно сделать для этого нового синтаксиса. Однако полная документация еще не опубликована для многих API.
Более причудливые методы обработки ошибок можно найти в
источник
Обработка ошибок - новая функция Swift 2.0. Он использует
try
,throw
иcatch
ключевые слова.См. Объявление Apple Swift 2.0 на официальном блоге Apple Swift.
источник
Хорошая и простая библиотека для обработки исключений: TryCatchFinally-Swift
Как и некоторые другие, он оборачивается объективными функциями C-исключений.
Используйте это так:
источник
Начиная с Swift 2, как уже упоминалось, обработка ошибок лучше всего достигается с помощью перечислений do / try / catch и ErrorType. Это работает довольно хорошо для синхронных методов, но для асинхронной обработки ошибок требуется немного хитрости.
Эта статья имеет отличный подход к этой проблеме:
https://jeremywsherman.com/blog/2015/06/17/using-swift-throws-with-completion-callbacks/
Подвести итоги:
тогда вызов вышеуказанного метода будет следующим:
Это выглядит немного чище, чем передача отдельного обратного вызова errorHandler в асинхронную функцию, как это было сделано до Swift 2.
источник
Что я видел, так это то, что из-за природы устройства вы не хотите, чтобы пользователь получал кучу загадочных сообщений об обработке ошибок. Вот почему большинство функций возвращают необязательные значения, а вы просто код, чтобы игнорировать необязательные. Если функция возвращается nil, что означает, что она не удалась, вы можете выдать сообщение или что-то еще.
источник