In Swift, it's rare but possible to end up with a value of a non-optional type that has a nil value. As explained in answers to this question, this can be caused by bad Objective-C code bridged to Swift:
- (NSObject * _Nonnull)someObject {
return nil;
}
Or by bad Swift code:
class C {}
let x: C? = nil
let y: C = unsafeBitCast(x, to: C.self)
In practice, I've run into this with the MFMailComposeViewController
API in MessageUI
. The following creates a non-optional MFMailComposeViewController
, but if the user has not set up an email account in Mail, the following code crashes with EXC_BAD_ACCESS
:
let mailComposeViewController = MFMailComposeViewController()
print("\(mailComposeViewController)")
The debugger shows the value of mailComposeViewController
like this:
mailComposeViewController = (MFMailComposeViewController) 0x0000000000000000
I have a couple of questions here:
- I note that the documentation for
unsafeBitCast(_:to:)
says it "breaks the guarantees of the Swift type system," but is there a place in Swift documentation that explains that these guarantees can be broken, and how/when? - What's the idiomatic way to check for this case? The compiler won't let me check whether
mailComposeViewController == nil
since it's not optional.