I have a swift UIViewController in which there is an array of data type ( e.g. countries/person/ bank details) fetched from network service asynchronously in viewDidLoad. This array remains constant once fetched. Hence I want to enforce it using let keyword.
I don't have any value when UIViewController is initialized. Hence it gives me compile time error for not initializing it.
If I declare it as optional with '?' , I have to use if-let/ guard let or optional chaining to use it. I don't want to clutter the code with unwrapping.
What are my options to declare a variable as constant but initialized later in execution without making it an optional variable?
"Constant once fetched" is not constant. There is some period of time when it's not set, and some point later when it is. The fact that it's fetched from the network means that it may fail, so your code has to deal with that (i.e. it may never be set). The right tool to use here is an Optional var.
Since there must be some view state that handles "no data yet" and a different view state that handles "data received," you can improve your design by breaking those into two view controllers, and having your container view controller switch between them when the data becomes available. In that case, you can pass the available data to the "data received" view controller in init, and so it can be let.
What are my options to declare a variable as constant but initialized later
There are no such options. If you do not have the real value of a property at instantiation time, it must be declared with var so that you can set it when you do have the real value.
And use of an Optional is a common pattern to help your code distinguish between before you have the real value (nil) and after (not nil).
I don't want to clutter the code with unwrapping.
Then declare the property as an implicitly unwrapped Optional! This use case is exactly what it is good for.
(It would be nice to be able to “lock” the property somehow after assigning its final value, but that is not a Swift language feature. I have often wished it were. lazy has the same issue.)
Why would you create a "Implicitly Unwrapped Optional" vs creating just a regular variable or constant?
If you know that it can be successfully unwrapped then why create an optional in the first place?
For example, why is this:
let someString: String! = "this is the string"
going to be more useful than:
let someString: String = "this is the string"
If ”optionals indicate that a constant or variable is allowed to have 'no value'”, but “sometimes it is clear from a program’s structure that an optional will always have a value after that value is first set”, what is the point of making it an optional in the first place?
If you know an optional is always going to have a value, doesn't that make it not optional?
Before I can describe the use cases for Implicitly Unwrapped Optionals, you should already understand what Optionals and Implicitly Unwrapped Optionals are in Swift. If you do not, I recommend you first read my article on optionals
When To Use An Implicitly Unwrapped Optional
There are two main reasons that one would create an Implicitly Unwrapped Optional. All have to do with defining a variable that will never be accessed when nil because otherwise, the Swift compiler will always force you to explicitly unwrap an Optional.
1. A Constant That Cannot Be Defined During Initialization
Every member constant must have a value by the time initialization is complete. Sometimes, a constant cannot be initialized with its correct value during initialization, but it can still be guaranteed to have a value before being accessed.
Using an Optional variable gets around this issue because an Optional is automatically initialized with nil and the value it will eventually contain will still be immutable. However, it can be a pain to be constantly unwrapping a variable that you know for sure is not nil. Implicitly Unwrapped Optionals achieve the same benefits as an Optional with the added benefit that one does not have to explicitly unwrap it everywhere.
A great example of this is when a member variable cannot be initialized in a UIView subclass until the view is loaded:
class MyView: UIView {
#IBOutlet var button: UIButton!
var buttonOriginalWidth: CGFloat!
override func awakeFromNib() {
self.buttonOriginalWidth = self.button.frame.size.width
}
}
Here, you cannot calculate the original width of the button until the view loads, but you know that awakeFromNib will be called before any other method on the view (other than initialization). Instead of forcing the value to be explicitly unwrapped pointlessly all over your class, you can declare it as an Implicitly Unwrapped Optional.
2. When Your App Cannot Recover From a Variable Being nil
This should be extremely rare, but if your app can not continue to run if a variable is nil when accessed, it would be a waste of time to bother testing it for nil. Normally if you have a condition that must absolutely be true for your app to continue running, you would use an assert. An Implicitly Unwrapped Optional has an assert for nil built right into it. Even then, it is often good to unwrap the optional and use a more descriptive assert if it is nil.
When Not To Use An Implicitly Unwrapped Optional
1. Lazily Calculated Member Variables
Sometimes you have a member variable that should never be nil, but it cannot be set to the correct value during initialization. One solution is to use an Implicitly Unwrapped Optional, but a better way is to use a lazy variable:
class FileSystemItem {
}
class Directory : FileSystemItem {
lazy var contents : [FileSystemItem] = {
var loadedContents = [FileSystemItem]()
// load contents and append to loadedContents
return loadedContents
}()
}
Now, the member variable contents is not initialized until the first time it is accessed. This gives the class a chance to get into the correct state before calculating the initial value.
Note: This may seem to contradict #1 from above. However, there is an important distinction to be made. The buttonOriginalWidth above must be set during viewDidLoad to prevent anyone changing the buttons width before the property is accessed.
2. Everywhere Else
For the most part, Implicitly Unwrapped Optionals should be avoided because if used mistakenly, your entire app will crash when it is accessed while nil. If you are ever not sure about whether a variable can be nil, always default to using a normal Optional. Unwrapping a variable that is never nil certainly doesn't hurt very much.
Consider the case of an object that may have nil properties while it's being constructed and configured, but is immutable and non-nil afterwards (NSImage is often treated this way, though in its case it's still useful to mutate sometimes). Implicitly unwrapped optionals would clean up its code a good deal, with relatively low loss of safety (as long as the one guarantee held, it would be safe).
(Edit) To be clear though: regular optionals are nearly always preferable.
Implicitly unwrapped optionals are useful for presenting a property as non-optional when really it needs to be optional under the covers. This is often necessary for "tying the knot" between two related objects that each need a reference to the other. It makes sense when neither reference is actually optional, but one of them needs to be nil while the pair is being initialized.
For example:
// These classes are buddies that never go anywhere without each other
class B {
var name : String
weak var myBuddyA : A!
init(name : String) {
self.name = name
}
}
class A {
var name : String
var myBuddyB : B
init(name : String) {
self.name = name
myBuddyB = B(name:"\(name)'s buddy B")
myBuddyB.myBuddyA = self
}
}
var a = A(name:"Big A")
println(a.myBuddyB.name) // prints "Big A's buddy B"
Any B instance should always have a valid myBuddyA reference, so we don't want to make the user treat it as optional, but we need it to be optional so that we can construct a B before we have an A to refer to.
HOWEVER! This sort of mutual reference requirement is often an indication of tight coupling and poor design. If you find yourself relying on implicitly unwrapped optionals you should probably consider refactoring to eliminate the cross-dependencies.
Implicitly unwrapped optionals are pragmatic compromise to make the work in hybrid environment that has to interoperate with existing Cocoa frameworks and their conventions more pleasant, while also allowing for stepwise migration into safer programing paradigm — without null pointers — enforced by the Swift compiler.
Swift book, in The Basics chapter, section Implicitly Unwrapped Optionals says:
Implicitly unwrapped optionals are useful when an optional’s value is confirmed to exist immediately after the optional is first defined and can definitely be assumed to exist at every point thereafter. The primary use of implicitly unwrapped optionals in Swift is during class initialization, as described in Unowned References and Implicitly Unwrapped Optional Properties.
…
You can think of an implicitly unwrapped optional as giving permission for the optional to be unwrapped automatically whenever it is used. Rather than placing an exclamation mark after the optional’s name each time you use it, you place an exclamation mark after the optional’s type when you declare it.
This comes down to use cases where the non-nil-ness of properties is established via usage convention, and can not be enforced by compiler during the class initialization. For example, the UIViewController properties that are initialized from NIBs or Storyboards, where the initialization is split into separate phases, but after the viewDidLoad() you can assume that properties generally exist. Otherwise, in order to satisfy the compiler, you had to be using the
forced unwrapping,
optional binding
or optional chaining
only to obscure the main purpose of the code.
Above part from the Swift book refers also to the Automatic Reference Counting chapter:
However, there is a third scenario, in which both properties should always have a value, and neither property should ever be nil once initialization is complete. In this scenario, it is useful to combine an unowned property on one class with an implicitly unwrapped optional property on the other class.
This enables both properties to be accessed directly (without optional unwrapping) once initialization is complete, while still avoiding a reference cycle.
This comes down to the quirks of not being a garbage collected language, therefore the breaking of retain cycles is on you as a programmer and implicitly unwrapped optionals are a tool to hide this quirk.
That covers the “When to use implicitly unwrapped optionals in your code?” question. As an application developer, you’ll mostly encounter them in method signatures of libraries written in Objective-C, which doesn’t have the ability to express optional types.
From Using Swift with Cocoa and Objective-C, section Working with nil:
Because Objective-C does not make any guarantees that an object is non-nil, Swift makes all classes in argument types and return types optional in imported Objective-C APIs. Before you use an Objective-C object, you should check to ensure that it is not missing.
In some cases, you might be absolutely certain that an Objective-C method or property never returns a nil object reference. To make objects in this special scenario more convenient to work with, Swift imports object types as implicitly unwrapped optionals. Implicitly unwrapped optional types include all of the safety features of optional types. In addition, you can access the value directly without checking for nil or unwrapping it yourself. When you access the value in this kind of optional type without safely unwrapping it first, the implicitly unwrapped optional checks whether the value is missing. If the value is missing, a runtime error occurs. As a result, you should always check and unwrap an implicitly unwrapped optional yourself, unless you are sure that the value cannot be missing.
...and beyond here lay
One-line (or several-line) simple examples don't cover the behavior of optionals very well — yeah, if you declare a variable and provide it with a value right away, there's no point in an optional.
The best case I've seen so far is setup that happens after object initialization, followed by use that's "guaranteed" to follow that setup, e.g. in a view controller:
class MyViewController: UIViewController {
var screenSize: CGSize?
override func viewDidLoad {
super.viewDidLoad()
screenSize = view.frame.size
}
#IBAction printSize(sender: UIButton) {
println("Screen size: \(screenSize!)")
}
}
We know printSize will be called after the view is loaded — it's an action method hooked up to a control inside that view, and we made sure not to call it otherwise. So we can save ourselves some optional-checking/binding with the !. Swift can't recognize that guarantee (at least until Apple solves the halting problem), so you tell the compiler it exists.
This breaks type safety to some degree, though. Anyplace you have an implicitly unwrapped optional is a place your app can crash if your "guarantee" doesn't always hold, so it's a feature to use sparingly. Besides, using ! all the time makes it sound like you're yelling, and nobody likes that.
Apple gives a great example in The Swift Programming Language -> Automatic Reference Counting -> Resolving Strong Reference Cycles Between Class Instances -> Unowned References and Implicitly Unwrapped Optional Properties
class Country {
let name: String
var capitalCity: City! // Apple finally correct this line until 2.0 Prerelease (let -> var)
init(name: String, capitalName: String) {
self.name = name
self.capitalCity = City(name: capitalName, country: self)
}
}
class City {
let name: String
unowned let country: Country
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
The initializer for City is called from within the initializer for Country. However, the initializer for Country cannot pass self to the City initializer until a new Country instance is fully initialized, as described in Two-Phase Initialization.
To cope with this requirement, you declare the capitalCity property of Country as an implicitly unwrapped optional property.
The rationale of implicit optionals is easier to explain by first looking at the rationale for forced unwrapping.
Forced unwrapping of an optional (implicit or not), using the ! operator, means you're certain that your code has no bugs and the optional already has a value where it is being unwrapped. Without the ! operator, you would probably just assert with an optional binding:
if let value = optionalWhichTotallyHasAValue {
println("\(value)")
} else {
assert(false)
}
which is not as nice as
println("\(value!)")
Now, implicit optionals let you express having an optional which you expect to always to have a value when unwrapped, in all possible flows. So it just goes a step further in helping you - by relaxing the requirement of writing the ! to unwrap each time, and ensuring that the runtime will still error in case your assumptions about the flow are wrong.
If you know for sure, a value return from an optional instead of nil, Implicitly Unwrapped Optionals use to directly catch those values from optionals and non optionals can't.
//Optional string with a value
let optionalString: String? = "This is an optional String"
//Declaration of an Implicitly Unwrapped Optional String
let implicitlyUnwrappedOptionalString: String!
//Declaration of a non Optional String
let nonOptionalString: String
//Here you can catch the value of an optional
implicitlyUnwrappedOptionalString = optionalString
//Here you can't catch the value of an optional and this will cause an error
nonOptionalString = optionalString
So this is the difference between use of
let someString : String! and let someString : String
Implicitly Unwrapped Optional(IUO)
It is a syntactic sugar for Optional that does not force a programmer to unwrap a variable. It can be used for a variable which can not be initialised during two-phase initialization process and implies non-nil. This variable behaves itself as non-nil but actually is an optional variable. A good example is - Interface Builder's outlets
Optional usually are preferable
var implicitlyUnwrappedOptional: String! //<- Implicitly Unwrapped Optional
var nonNil: String = ""
var optional: String?
func foo() {
//get a value
nonNil.count
optional?.count
//Danderour - makes a force unwrapping which can throw a runtime error
implicitlyUnwrappedOptional.count
//assign to nil
// nonNil = nil //Compile error - 'nil' cannot be assigned to type 'String'
optional = nil
implicitlyUnwrappedOptional = nil
}
I think Optional is a bad name for this construct that confuses a lot of beginners.
Other languages (Kotlin and C# for example) use the term Nullable, and it makes it a lot easier to understand this.
Nullable means you can assign a null value to a variable of this type. So if it's Nullable<SomeClassType>, you can assign nulls to it, if it's just SomeClassType, you can't. That's just how Swift works.
Why use them? Well, sometimes you need to have nulls, that's why. For example, when you know that you want to have a field in a class, but you can't assign it to anything when you are creating an instance of that class, but you will later on. I won't give examples, because people have already provided them on here. I'm just writing this up to give my 2 cents.
Btw, I suggest you look at how this works in other languages, like Kotlin and C#.
Here's a link explaining this feature in Kotlin:
https://kotlinlang.org/docs/reference/null-safety.html
Other languages, like Java and Scala do have Optionals, but they work differently from Optionals in Swift, because Java and Scala's types are all nullable by default.
All in all, I think that this feature should have been named Nullable in Swift, and not Optional...
What is difference between
self?.profile!.id!
and
(self?.profile!.id!)!
XCode converts first to second.
The first one contains self? which means self is optional, leads to let related properties (profile!.id! in your case) related to the existence of the self which is Optional Chaining:
Optional chaining is a process for querying and calling properties,
methods, and subscripts on an optional that might currently be nil. If
the optional contains a value, the property, method, or subscript call
succeeds; if the optional is nil, the property, method, or subscript
call returns nil. Multiple queries can be chained together, and the
entire chain fails gracefully if any link in the chain is nil.
To make it more simpler, you could think of id! nullity is also optional, even if you force unwrapping it, because it is related to the existence of self; If self is nil, profile and id will be also nil implicitly because they are related to the existence of self.
Mentioning: (self?.profile!.id!)! means that the whole value of the chain would be force wrapped.
Note that implementing:
self!.profile!.id!
leads to the same output of
(self?.profile!.id!)!
since self! is force unwrapped, the value of id would not be related to the nullity of self because the compiler assumes that self will always has a value.
However, this approach is unsafe, you should go with optional binding.
First of all you are using too many question and exclamation marks!!!
Practically there is no difference. The result is a forced-unwrapped optional.
Usually Xcode suggests that syntax if the result of the last item of the chaining is a non-optional so the exclamation mark would cause an error for example
text?.count!
Then Xcode suggests
(text?.count)!
but in this case be brave and write
text!.count
In Apple's blog on nullability, they mention this:
"...in Swift there’s a strong distinction between optional and
non-optional references, e.g. NSView vs. NSView?, while Objective-C
represents boths of these two types as NSView *. Because the Swift
compiler can’t be sure whether a particular NSView * is optional or
not, the type is brought into Swift as an implicitly unwrapped
optional, NSView!"
Does that mean previously when declaring Objective-C methods as returning implicitly unwrapped optional in Swift, it can in fact crash (since some of the methods declared with implicitly unwrapped optional may return nil)? Or does Apple make sure only those Objective-C methods that absolutely do not return nil get declared as implicitly unwrapped optional?
Apple's frameworks aren't anything special. In the beginning, everything (every object) you used from Objective-C in Swift was an implicitly unwrapped optional. That was because every pointer in Objective-C could possibly return nil.
In fact, even in the era of Objective-C nullability annotations, it's not entirely impossible that a method annotated as nonnull could return nil. Objective-C doesn't enforce the nullability rules, it merely provides a means for annotating your code so that it should be safer to use from Swift. In the case of Apple's frameworks, I'd wager it's a pretty safe bet that you won't have this problem. Or if you do, the next version of Xcode will fix it.
But again, there's nothing special about implicitly unwrapped optionals coming from Objective-C libraries and frameworks. The only thing that an implicitly unwrapped optional tells you is that the framework author has not made the effort to annotate their library yet (you can't leave implicitly unwrapped optionals in an annotated library). And yes, these implicitly unwrapped options can be nil and they can crash your application.
In the case of Apple, if for some reason, you're using say Xcode 7 and Xcode 6 on different projects, if you take something which Xcode 7's update annotations have declared as non-optional, then assuming the implicitly unwrapped optional version in Xcode 6 will never be nil might work out. But if you take something that is an optional in Xcode 7, assuming the implicitly unwrapped version from Xcode 6 will never be nil probably has a decent likelihood of crashing your app.
Ultimately, in Swift, our use of implicitly unwrapped optionals should be few and far between. The primary use of implicitly unwrapped optionals should mostly be reserved for class properties which cannot be set before the class initialization has returned (for example, #IBOutlets in a view controller). Otherwise, they're prone to being the source of numerous "Unexpectedly found nil" questions here on Stack Overflow.
To the question of "Why return an implicitly unwrapped optional rather than an optional?", a few points...
First, that's a language design question. I'm not on the Objective-C or Swift language design team and it's unlikely that anyone from those teams will stop by and answer that question...
Second, that's how the languages are designed to interoperate. Any Objective-C file which has not had nullability annotations added will be treated as if everything is an implicitly unwrapped optional in Swift.
Third, the reason for implicit optionals is it reduces a lot of the verbosity of if let etc statements that optional would require, while not guaranteeing that the variable is actually non-nil. Most of the reason for this is probably because you figure most of these methods actually never return nil.
Fourth, if you know which ones have a chance to be nil and which ones don't, you can actually go ahead and write your Swift code in a way which handles both making assumptions about which way the Objective-C code will be annotated.
For example, with an implicitly unwrapped optional, of course, you can treat it like a non-optional and remove some of the minor verbosity involved with unwrapping.
Additionally, with an implicitly unwrapped optional, if you think it might be nil, all of the optional unwrapping stuff can still work with it.
Example:
override func someFunc(implicitVal: String!) -> String {
return implicitVal ?? "It was nil!"
}
override func someOtherFunc(implicitVal: String!) -> String {
return implicitVal
}
If we assumed them all as optionals, the second example wouldn't work
If we assumed them as non-optionals, the first example wouldn't work.
Implicitly unwrapped optionals allows the freedom for the Swift developer to treat them as either if they make the right assumption about the likelihood of the value being nil.
Does that mean previously when declaring Objective-C methods as
returning implicitly unwrapped optional in Swift, it can in fact crash
(since some of the methods declared with implicitly unwrapped optional
may return nil)?
No. An implicitly-unwrapped optional is an optional -- which means nil is a perfectly acceptable value for it. Having an implicitly-unwrapped optional as nil doesn't crash, only if you try to access a member on it directly without optional-binding or optional-chaining does it crash.
Or does Apple make sure only those Objective-C
methods that absolutely do not return nil get declared as implicitly
unwrapped optional?
If it were known to not return nil, then Apple, after auditing, would declare it as non-optional, not an implicitly-unwrapped optional. Only if it is not known whether it may return nil or not, does it return implicitly-unwrapped optional.
If I have property like:
var animatedImagesView:JSAnimatedImagesView?
And eventually it gets initialized at the proper time, do I need to just keep using ! to unwrap it ad nauseum when I want to do something to it? For instance:
self.animatedImagesView!.reloadData()
Usually I unwrap optionals like:
if let dailySleepTime:AnyObject = uw_JSON["daily_sleep_time"] {
self.settings.dailySleepTime = dailySleepTime as String
} else {
log.warning("\n Error finding attr in \(request)\n")
}
but I can't just go around casting my properties to constants in the same way right? I'm not complaining, I'm just wondering if I'm using the exclamation point correctly.
One option is to define animatedImageView as an implicitly unwrapped optional to begin with:
var animatedImagesView: JSAnimatedImagesView!
This is common when dealing with Cocoa .nib objects in Interface Builder, because the View can't be initialized until it is unarchived from the .nib, but you know that it will always be initialized before you use it.
I hate using the ! in general, because it is a runtime error just waiting to happen, but IB objects are one of the few places where its use seems both legitimate and necessary. Otherwise, your two other options are the ones that you have already found - unwrapping it every time using if let... (which is safest, but a pain in the a**), or using the ! every time that you use it, which isn't any safer than just declaring it using ! to begin with.
If you initialize it at the correct time (for example in any of the lifecycle methods, or in the constructor for that matter) you could just use ! instead of ? for the property declaration. I myself usually only use ? for stuff which I dont necessarily know will have a value at all times during my lifecycle.
If the latter is the case for you as well, you need to continue using ? since you can't guarantee you have a value stored. And you should also use the if let myVar = myVar { .. } syntax if you do multiple calls to the variable.
Instead, declare it as follows:
var animatedImagesView:JSAnimatedImagesView!
That implicitly unwrapped optional will obviate the need to constantly "bang" dereference it, but be sure it is never nil at any time accessed.
It's a great way to specify IBOutlets you know will always be initialized from the nib or storyboard before you use them.