While talking about failable initializers, The Swift Programming Language Tutorial by Apple states that unlike value types, for classes, the failable initializer check for nil should come after all stored properties are initialized to a default value. Then, it moves on to suggest defining the stored properties as "implicitly unwrapped optionals" since that kind of a definition would set the stored property to nil
by default and satisfy the aforementioned requirement for the failable initializers for classes. Next, it provides the following example to show how this implicitly unwrapped optional thing can be applied:
Example taken from the tutorial (version 2015-9-16)
class Product {
let name: String!
init?(name: String) {
self.name = name
if name.isEmpty { return nil }
}
}
To me, there is a logical inconsistency between what is explained in the text and what this example illustrates. In my humble opinion, if we were to understand how defining the name
property as a String!
makes the failable initializer able to fail at the very beginning of the initialization - by satisfying the class' requirement of setting all stored properties to a default value - then I would expect the orders of the two statements in the init?
body to be interchanged as follows:
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
Only after that, we would understand that the name
property, which is defined as String!
, already has a default value when the initialization begins (which is nil
) and lets it to fail if it is being set to an empty string.
Moreover, I tried interchanging the order of those statements in a playground to see the effect and I got an error stating that "All stored properties should be initialized... etc".
Could you please clarify what's going on here?
Thanks in advance...
Edit:
I do not think that this post is a duplicate. I already read thoroughly the post, which you suggest to be answering the question.
Specifically, I think mustafa's answer is not an explanation to what I am asking. He answers the question of "why we need to initialize all the stored properties of an instance, which is about to return nil through its failable initializer". I acknowledge that this is due to a compiler limitation: Currently, the complier cannot destroy partially initialized class instances when necessary. Hence, they try to avoid conditions in which such instances may occur. So they suggest defining the name
property as aString!
in the example for instance. Why? Because, that definition will default the name
property to nil
. So, even if I do not assign any value to the property before trying to assign it to an empty string, the failable initializer will fail since it will consider the name
property to be set to a valid value, which is nil
.
However, what I say is, their suggestion does not provide the result they aim for. Why do I still get the error of "uninitialized stored property" if I write the statement self.name = name
after the isEmpty
check? If that suggestion was working, then this would not return any errors. Do I miss something here?
Hope, my question is a little bit clearer now. Thanks...