I haven't read too much into Swift but one thing I noticed is that there are no exceptions. So how do they do error handling in Swift? Has anyone found anything related to error-handling?
相关问题
- “Zero out” sensitive String data in Swift
- SwiftUI: UIImage (QRCode) does not load after call
- Get the NSRange for the visible text after scroll
- UIPanGestureRecognizer is not working in iOS 13
- What does a Firebase observer actually do?
相关文章
- Using if let syntax in switch statement
- Enum with associated value conforming to CaseItera
- Swift - hide pickerView after value selected
- Is there a Github markdown language identifier for
- How can I vertically align my status bar item text
- Adding TapGestureRecognizer to UILabel in Swift
- Attempt to present UIAlertController on View Contr
- Swift - Snapshotting a view that has not been rend
Error handling is a new feature of Swift 2.0. It uses the
try
,throw
andcatch
keywords.See the Apple Swift 2.0 announcement on the official Apple Swift blog
Swift 2 & 3
Things have changed a bit in Swift 2, as there is a new error-handling mechanism, that is somewhat more similar to exceptions but different in detail.
1. Indicating error possibility
If function/method wants to indicate that it may throw an error, it should contain
throws
keyword like thisNote: there is no specification for type of error the function actually can throw. This declaration simply states that the function can throw an instance of any type implementing ErrorType or is not throwing at all.
2. Invoking function that may throw errors
In order to invoke function you need to use try keyword, like this
this line should normally be present do-catch block like this
Note: catch clause use all the powerful features of Swift pattern matching so you are very flexible here.
You may decided to propagate the error, if your are calling a throwing function from a function that is itself marked with
throws
keyword:Alternatively, you can call throwing function using
try?
:This way you either get the return value or nil, if any error occurred. Using this way you do not get the error object.
Which means that you can also combine
try?
with useful statements like:or
Finally, you can decide that you know that error will not actually occur (e.g. because you have already checked are prerequisites) and use
try!
keyword:If the function actually throws an error, then you'll get a runtime error in your application and the application will terminate.
3. Throwing an error
In order to throw an error you use throw keyword like this
You can throw anything that conforms to
ErrorType
protocol. For startersNSError
conforms to this protocol but you probably would like to go with enum-basedErrorType
which enables you to group multiple related errors, potentially with additional pieces of data, like thisMain differences between new Swift 2 & 3 error mechanism and Java/C#/C++ style exceptions are follows:
do-catch
+try
+defer
vs traditionaltry-catch-finally
syntax.do-catch
block will not catch any NSException, and vice versa, for that you must use ObjC.NSError
method conventions of returning eitherfalse
(forBool
returning functions) ornil
(forAnyObject
returning functions) and passingNSErrorPointer
with error details.As an extra syntatic-sugar to ease error handling, there are two more concepts
defer
keyword) which let you achieve the same effect as finally blocks in Java/C#/etcguard
keyword) which let you write little less if/else code than in normal error checking/signaling code.Swift 1
Runtime errors:
As Leandros suggests for handling runtime errors (like network connectivity problems, parsing data, opening file, etc) you should use
NSError
like you did in ObjC, because the Foundation, AppKit, UIKit, etc report their errors in this way. So it's more framework thing than language thing.Another frequent pattern that is being used are separator success/failure blocks like in AFNetworking:
Still the failure block frequently received
NSError
instance, describing the error.Programmer errors:
For programmer errors (like out of bounds access of array element, invalid arguments passed to a function call, etc) you used exceptions in ObjC. Swift language does not seem to have any language support for exceptions (like
throw
,catch
, etc keyword). However, as documentation suggests it is running on the same runtime as ObjC, and therefore you are still able to throwNSExceptions
like this:You just cannot catch them in pure Swift, although you may opt for catching exceptions in ObjC code.
The questions is whether you should throw exceptions for programmer errors, or rather use assertions as Apple suggests in the language guide.
The recommended 'Swift Way' is:
However I prefer try/catch as I find it easier to follow because it moves the error handling to a separate block at the end, this arrangement is sometimes called "Golden Path". Lucky you can do this with closures:
Also it is easy to add a retry facility:
The listing for TryBool is:
You can write a similar class for testing an Optional returned value instead of Bool value:
The TryOptional version enforces a non-Optional return type that makes subsequent programming easier, e.g. 'Swift Way:
Using TryOptional:
Note auto-unwrapping.
There are no Exceptions in Swift, similar to Objective-C's approach.
In development, you can use
assert
to catch any errors which might appear, and need to be fixed before going to production.The classic
NSError
approach isn't altered, you send anNSErrorPointer
, which gets populated.Brief example:
Update June 9th 2015 - Very important
Swift 2.0 comes with
try
,throw
, andcatch
keywords and the most exciting is:Excerpt From: Apple Inc. “Using Swift with Cocoa and Objective-C (Swift 2 Prerelease).” iBooks.
Example: (from the book)
The equivalent in swift will be:
Throwing an Error:
Will be automatically propagated to the caller:
From Apple books, The Swift Programming Language it's seems errors should be handle using enum.
Here is an example from the book.
From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/br/jEUH0.l
Update
From Apple news books, "Using Swift with Cocoa and Objective-C". Runtime exceptions not occur using swift languages, so that's why you don't have try-catch. Instead you use Optional Chaining.
Here is a stretch from the book:
Excerpt From: Apple Inc. “Using Swift with Cocoa and Objective-C.” iBooks. https://itun.es/br/1u3-0.l
And the books also encourage you to use cocoa error pattern from Objective-C (NSError Object)
Excerpt From: Apple Inc. “Using Swift with Cocoa and Objective-C.” iBooks. https://itun.es/br/1u3-0.l
This is an update answer for swift 2.0. I am looking forward feature rich Error handling model like in java. Finally, they announced the good news. here
e.g :