This isn't quite a duplicate — there's some subtlety to implicitly unwrapped optionals in function signatures beyond their usage elsewhere.
You see implicitly unwrapped optionals in API imported from ObjC because that's the closest Swift approximation of an object that's expected to be there but which can be nil. It's a compromise for imported API — you can address these variables directly like in ObjC, and you can test them for nil using Swift optional syntax. (There's more about Apple's rationale for this in the Advanced Interoperability talk from WWDC14.) This pattern also applies to the IBAction
declarations inserted by Interface Builder, since those methods are in effect getting called from ObjC code, too.
As you seem to have suspected, Swift wraps the possible nil in an optional when bridging from ObjC, but the !
in your function implementation's declaration unwraps the value so you can use it directly. (At your own risk.)
Since Swift 1.2 (Xcode 6.2 in Spring 2015), ObjC APIs can be annotated with nonnull
and nullable
, in which case the Swift interface to those APIs uses either a non-optional type or a fully optional type. (And since Swift 2.0 / Xcode 7.0, nearly all of Apple's APIs are audited to use nullability annotations, so their Swift signatures don't use much !
anymore.)
What's less well-known about this is that you're free to change the optionality of parameters when you implement your own Swift functions that get called by ObjC. If you want the compiler to enforce that sender
in your action method can never be nil, you can take the !
off the parameter type. If you want the compiler to make sure you always test the parameter, change the !
to a ?
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…