What does it mean to "unwrap the instance"? Why is it necessary?
As far as I can work out (this is very new to me, too)...
The term "wrapped" implies we should think of an Optional variable as a present, wrapped in shiny paper, which might (sadly!) be empty.
When "wrapped", the value of an Optional variable is an enum with two possible values (a little like a Boolean). This enum describes whether the variable holds a value (Some(T)
), or not (None
).
If there is a value, this can be obtained by "unwrapping" the variable (obtaining the T
from Some(T)
).
How is john!.apartment = number73
different from john.apartment = number73
? (Paraphrased)
If you write the name of an Optional variable (eg text john
, without the !
), this refers to the "wrapped" enum (Some/None), not the value itself (T). So john
isn't an instance of Person
, and it doesn't have an apartment
member:
john.apartment
// 'Person?' does not have a member named 'apartment'
The actual Person
value can be unwrapped in various ways:
- "forced unwrapping":
john!
(gives the Person
value if it exists, runtime error if it is nil)
- "optional binding":
if let p = john { println(p) }
(executes the println
if the value exists)
- "optional chaining":
john?.learnAboutSwift()
(executes this made-up method if the value exists)
I guess you choose one of these ways to unwrap, depending upon what should happen in the nil case, and how likely that is. This language design forces the nil case to be handled explicitly, which I suppose improves safety over Obj-C (where it is easy to forget to handle the nil case).
Update:
The exclamation mark is also used in the syntax for declaring "Implicitly Unwrapped Optionals".
In the examples so far, the john
variable has been declared as var john:Person?
, and it is an Optional. If you want the actual value of that variable, you must unwrap it, using one of the three methods above.
If it were declared as var john:Person!
instead, the variable would be an Implicitly Unwrapped Optional (see the section with this heading in Apple's book). There is no need to unwrap this kind of variable when accessing the value, and john
can be used without additional syntax. But Apple's book says:
Implicitly unwrapped optionals should not be used when there is a possibility of a variable becoming nil at a later point. Always use a normal optional type if you need to check for a nil value during the lifetime of a variable.
Update 2:
The article "Interesting Swift Features" by Mike Ash gives some motivation for optional types. I think it is great, clear writing.
Update 3:
Another useful article about the implicitly unwrapped optional use for the exclamation mark: "Swift and the Last Mile" by Chris Adamson. The article explains that this is a pragmatic measure by Apple used to declare the types used by their Objective-C frameworks which might contain nil. Declaring a type as optional (using ?
) or implicitly unwrapped (using !
) is "a tradeoff between safety and convenience". In the examples given in the article, Apple have chosen to declare the types as implicitly unwrapped, making the calling code more convenient, but less safe.
Perhaps Apple might comb through their frameworks in the future, removing the uncertainty of implicitly unwrapped ("probably never nil") parameters and replacing them with optional ("certainly could be nil in particular [hopefully, documented!] circumstances") or standard non-optional ("is never nil") declarations, based on the exact behaviour of their Objective-C code.
Problem Solved.
As McDowell mentioned before, problem was about encoding settings. Best way to overcome this problem is declaring encoding info from WTK.
Within your working directory, find ktools.properties file ('workdir\wtklib\ktools.properties' or 'workdir\wtklib\Linux\ktools.properties' as is on my machine). And add the following lines:
microedition.encoding= *encoding*
For ASCII encoding:
microedition.encoding=ISO8859_1
That will do the job (:
Best Answer
The
@State
keyword is a@propertyWrapper
, a feature just recently introduced in Swift 5.1. As explained in the corresponding proposal, it's sort of a value wrapper avoiding boilerplate code.Sidenote:
@propertyWrapper
has previously been called@propertyDelegate
, but that has changed since. See this post for more information.The official @State documentation has the following to say:
So when you initialize a property that's marked
@State
, you're not actually creating your own variable, but rather promptingSwiftUI
to create "something" in the background that stores what you set and monitors it from now on! Your@State var
just acts as a delegate to access this wrapper.Every time your
@State
variable is written,SwiftUI
will know as it is monitoring it. It will also know whether the@State
variable was read from theView
'sbody
. Using this information, it will be able to recompute anyView
having referenced a@State
variable in itsbody
after a change to this variable.