http://stackoverflow.com/questions/30068200/returning-an-unwrapped-optional-in-swift
http://stackoverflow.com/questions/24728235/why-do-objective-c-apis-return-implicitly-unwrapped-optionals?rq=1
Implicitly unwrapped optional is basically an optional, that gets an ! everywhere you use it. Thats it.
e.g.:
1 2 3 |
//this: var number: Int? = ... print(number!) |
is the same as this:
1 2 |
var number: Int! = ... print(number) |
An implicitly unwrapped optional is only to save you the need of unwrapping it every time you use it, wether with if let or with an !, but it has the same optionality of being nil as a normal optional.
An implicitly unwrapped optional is still an optional – it could be nil. If you simply write self.device.hasFlash, when self.device is nil, you will get an exception.
When you make an implicitly unwrapped optional in Swift, it does not mean that it is always going to be non-nil: all it means is that you tell the compiler that when you access their properties, you expect the object to be non-nil. The object that you reference can be explicitly checked for nil; setting it to nil will not cause an exception either, unless you try to access any of its properties after that.
When Apple used implicitly unwrapped optionals for the parameters of
1 |
func tableView(_ tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! |
function, they let you save on a few extra if – let. In this case, they know that they never pass you a nil; in other cases, they do not know it, and they expect you to nil-check the object.
They allow you to return nil, too. It is up to them to check the results for nil, unless, of course, you decide to call that function yourself. Although I cannot think of a valid reason to call cellForRowAtIndexPath from your own code, if you do make a call, it would be your responsibility to check the return value for nil.
example
1 2 3 4 |
//it does not mean its always going to non-nil. private func test() -> String! { return "Ricky" } |
you can check like so:
1 2 3 4 5 |
if (self.test() == nil) { print("uh oh :( its nil") } else { print("not nil") } |
What if we used ?
If you consider an alternative of making the parameters UITableView? and NSIndexPath? instead, all implementations would have to either use an exclamation point after tableView and indexPath, or use the if – let idiom. Compared to this choice, implicitly unwrapped types look like a better choice.
Sample
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// String! simply means optional (however, can use as is, don't need if-let ) private func test() -> String! { // create optional var temp: String? // NOTICE WE DECLARED 'OPTIONAL' // assign it temp = "haha" print(temp) // Optional("haha") print(temp!) // "haha" return temp! //returning optional } // t is defaulted to be of type 'Optional' let t = test() if(t != nil) { print(t) // Optional("haha") print(t!) // "haha" } |
If we change the temp variable to implicit optional, everything is same, because after all, we are dealing with an optional. However the characteristics involved is that we don’t need to use if-let. The variable is “implied” that we want to unwrap it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// String! simply means optional (however, can use as is, don't need if-let ) private func test() -> String! { var temp: String! //Notice 'implicit unwrapped' Optional // assign it temp = "haha" print(temp) // "haha" print(temp!) // "haha" return temp! //returning optional } // t is defaulted to an optional let t = test() if(t != nil) { print(t) // Optional("haha") print(t!) // "haha" } |
Now, we use an implicity unwrapped Optional, hence, we simply use temp in the print function for its unwrapped value.
Another thing to notice is that let t is an optional. Thus, as an optional, you still need to force unwrap it to get the value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// String! simply means optional (however, can use as is, don't need if-let ) private func test() -> String! { // create optional var temp: String! // assign it temp = "haha" print(temp) // "haha" print(temp!) // "haha" return temp! } let t : String! //declare it as 'implicit unwrapped' optional t = test() if(t != nil) { print(t) // "haha" print(t!) // "haha" } |
Returning a Optional or Implicit Unwrapped Optional does not matter. What matters is whether the variable taking on the return value is of Optional or Implicit Optional.