Swift : non-nil optional value raising a nil exception
it's an outlet to a textfield but it seems to not unwrap in the prepareForSegue function
That comment reveals your misconception. Things happen in a order, which I discuss here: https://stackoverflow.com/a/29552710/341994
So, by design, prepareForSegue
happens before the new view controller has its view - or its outlets. Conversely, the first moment when its outlets are connected is its own viewDidLoad
, which is later.
Your real mistake, though, is deeper. One view controller has no business setting or talking to another view controller's outlets and thus manipulating its interface. Instead, set things up so that the destination view controller has an ordinary property which you can set. In viewDidLoad
, that view controller than checks that property, retrieves the value, and sets its own interface through its outlet.
So, to sum up: prepareForSegue
is your chance to initialize the new view controller. But that's all. The new view controller will then later control its own view — as the name implies! And it will do this starting in its own viewDidLoad
and later.
How to avoid returning an optional after throwing an exception?
You can use Swift assert(_:_file:line:)
function as follows
assert(some condition, "Message to display if condition is false (optional)" )
If the condition is verified the app will continue running, otherwise it will terminate
Throwing on unwrapping nil optional
It looks ok, but it's even better with guard let
instead of if let
because it lets you use the unwrapped value in the main do
block instead of having to work inside an if let
branch. You can also use several catch
branches to handle different error types.
do {
guard let value = mightHaveAValue else {
throw MyErrorType.BadTimes
}
// do stuff with value
} catch let error as MyErrorType {
// handle custom error
} catch let error as NSError {
// handle generic NSError
}
There is no automatic way to handle unwrapping optionals, you have to use one of the many known ways: if let
, guard let
, nil coalescing, etc.
How to avoid returning an optional after throwing an exception?
You can use Swift assert(_:_file:line:)
function as follows
assert(some condition, "Message to display if condition is false (optional)" )
If the condition is verified the app will continue running, otherwise it will terminate
swift force-unwrapping exception not propagated
From the documentation:
Error Handling
Error handling is the process of responding to and recovering from
error conditions in your program. Swift provides first-class support
for throwing, catching, propagating, and manipulating recoverable
errors at runtime....
Representing and Throwing Errors
In Swift, errors are represented by values of types that conform to
theErrorType
protocol. This empty protocol indicates that a type can
be used for error handling.
(Note: ErrorType
has been renamed to Error
in Swift 3)
So with try/catch
you handle Swift errors (values of types that conform to the ErrorType
protocol) which are throw
n.
This is completely unrelated to runtime errors and runtime exceptions
(and also unrelated to NSException
from the Foundation library).
Note that the Swift documentation on error handling does not even use the
word "exception", with the only exception (!) in (emphasis mine) in:
NOTE
Error handling in Swift resembles exception handling in other
languages, with the use of the try, catch and throw keywords. Unlike
exception handling in many languages—including Objective-C—error
handling in Swift does not involve unwinding the call stack, a process
that can be computationally expensive. As such, the performance
characteristics of a throw statement are comparable to those of a
return statement.
The unwrapping of optionals which are nil
does not throw
a
Swift error (which could be propagated) and cannot be handled withtry
.
You have to use the well-known techniques like
optional binding, optional chaining, checking against nil
etc.
Swift app stops running after an error
I think you are overusing the !
(force unwrap) symbol here. It does not deal gracefully with nil values, in fact, it crashes.
I think what you might want to be doing here is
guard
let ps: Element = try? doc.getElementById("product-name"),
let ide = try? ps.text()
else {
print("error")
ide = ""
}
// ide is guaranteed to be valid here
...
Note how if you use try?
you do not need to "catch" the error, it will simply return an optional value, nil
if the call would raise an exception.
Alternatively you could simply
let ps: Element = try? doc.getElementById("product-name")
let ide = try? ps?.text()
// ide will be an optional value here
If you really don't want to guard
/if let
...
Related Topics
How to Intercept Push Notifications for Another App
How to Change Font of Uibutton with Swift
How to Get Distance of Object from iPhone Camera Using Image Exif Meta Data
Color in Storyboard Not Matching Uicolor
What's Dead & Exploded in Swift's Exception Stack
Number of Threads Created by Gcd
How to Set-Up in App Purchase Free Trial Period in iOS App
Change App Version with Only IPA File Provided (No Xcode)
Sectionindextitles for a Uicollectionview
Opening a PDF Document When Clicking a Button
Differencebetween Embedded Binaries and Linked Frameworks
Launch a Local Notification at a Specific Time in iOS
Using Convertpoint to Get the Relative Position Inside a Parent Uiview
Allow Unverified Ssl Certificates in Wkwebview
Which Tasks Are More Suitable to Nsoperation Than Gcd
iOS 9 Searchbar Disappears from Table Header View When Uisearchcontroller Is Active