Reputation: 7183
I've seen a lot of discussion regarding variables in Swift that are declared as var a: String?
and var a: String!
the former being an optional variable of type String and the latter being implicitly unwrapped optional String. From my understanding, when something is implicitly unwrapped there's an assumption being made that there's a value already included in the optional value. In order to use the syntax a!.toInt()
there would have to be an outside check like so:
if a != nil {
a!.toInt()
}
As a side note, it seems better practice to just declare variables as an optional type and then use optional chaining to unwrap the value if it exists. Doing:
if let numberString = a?.toInt() {
numberString.toInt()
}
Is there a scenario in where accessing a variable like a!.toInt()
should ever be used in practical applications? To me, it seems like you'd be asking for runtime errors.
Now for the actual question. I was looking through the documentation, specifically enumerateObjectsUsingBlock
on NSArray
and the block parameter is declared using an !
. Does this mean that the writers of that function are assuming that the block parameter will be non-nil? If so, inside that function, what is the semantic difference between:
func someMethodWithBlock(block:((String!)-> Void)!) {
var a = "Hello"
block.(a) //first syntax example
block?.(a)//2nd
block!.(a)//3rd
}
Upvotes: 1
Views: 328
Reputation: 118761
Implicitly Unwrapped Optionals are used almost everywhere in the Cocoa APIs as they are imported into Swift — this is to maintain compatibility with the kind of pointer semantics that are ubiquitous in Obj-C, without requiring !
s and ?
s all over the place. That's why the NSArray
method's block takes a String!
argument.
In Swift, regular Optionals (Int?
, etc.) are largely preferable for the reasons you specified: they are less prone to errors. Implicitly Unwrapped Optionals are mostly meant to be used only in certain cases, like when you need to pass self
to a function before initialization is complete. (If you know a variable is not nil, unwrapping it like a!.toInt()
is just fine. The danger with IUOs is that it would be written a.toInt()
, and to a reader this looks completely safe, when in reality it's not.)
Upvotes: 2