What must be accomplished in the implementation of an initializer?
a. All properties need to be initialized with a value
b. All properties need to be explicitly assigned a value.
c. All non-Optional properties need to be initialized.
Sorry, that's incorrect.
Optionals need to be initialized as well.
d. The object needs to be created
What answer is correct and why?
In my opinion that is very confusingly stated question. Because what you as the developer have to do is Option c.
Take a look at this simple code example and the minimum init to be compilable
class SomeClass {
var a : AnyObject
var b : AnyObject?
var c : AnyObject!
var d = ":)"
init() {
a = ""
print("initialized")
}
}
The swift docu states
Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state.
You can set an initial value for a stored property within an initializer, or by assigning a default property value as part of the property’s definition. These actions are described in the following sections.
Option d. is imho non-sense since the object creation is handled by the underlying runtime environment and not via the initializer.
Now b. and a. remain with the tiny difference in wording explicitly assigned vs. initialized. I would therefore discard Option b because the b and c variable do not need any explicit value, the implicit nil is perfectly fine for the time (reading c will not work yet though)
Therefore my answer choice would be Option a. After the init method all properties need to have some specific value. Some of them explicitly in the init function, some of them implicitly.
tl;dr:
my final answer is Option a.
Related
I am pretty new to swift .
I found the following document from Apple.
Classes and structures must set all of their stored properties to an
appropriate initial value by the time an instance of that class or
structure is created. Stored properties cannot be left in an
indeterminate state.
You can set an initial value for a stored property within an
initializer, or by assigning a default property value as part of the
property’s definition. These actions are described in the following
sections.
but the below piece of code noOfTyres is not initialised and the compiler doesn't complain ,please explain this .
class Vehicle
{
var noOfTyres: Int!
var engineCapacity: Int
init()
{
engineCapacity = 10
}
}
In your case, the compiler won't complain, until you try to use that value. Because you have the value un-wrapped (!) it assumes that it will never be nil and trying to access the value, will crash.
In this case I would add a default value to the property noOfTyres.
var noOfTyres: Int = 2
Or, you can add the value in the constructor to make sure that everytime an object gets created, the value must be set.
class Vehicle
{
var noOfTyres : Int!
var engineCapacity :Int
init(noOfTyres: Int)
{
self.noOfTyres = noOfTyres
engineCapacity=10;
}
}
Remember, if it's not optional, you are saying, the property will never be nil.
Another thing, by convention class names must be capitalized.
You can declare a stored property without assigning it an initial value if you make this property an optional. The property then either has a value or it is nil. An optional property is either declared with
var myOptional : Int?
or
var myOptional : Int!
And therefore noOfTyres is not initialized, while it is an optional and currently it is set to nil.
For more information, please, read the Apple documentation.
Additional information. The different types of optional declaration (! and ?) are explained in this post.
I am not sure ,if this can be the answer
The documentation 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.
Hence its expected by the compiler as initialised ,definitely containing a value.But If we access it without a value during run time it will crash
If using an optional as a stored property ,it will have atlas a nil value & for other stored properties ,need an initialisation.
I just started learning Swift and recently found out about
"Normal" variables (for lack of a better name):
ex: var test1: String
"Optional" variables
ex: var test2: String?
"Implicitly Unwrapped Optionals"
ex: var test3: String!
Lazy variables
ex: lazy var test4: String
My understanding is this:
Use "Optional" variables (?) when the variable may or may not be initialized at points in the future starting from initialization
Use "Implicitly Unwrapped Optionals" (!) when the variable is guaranteed to be initialized
Optionals can be converted to Implicitly Unwrapped Optionals via "Forced Unwrapping"
ex: let possibleString: String? = "Hello"
println(possibleString!)
Use "Lazy variables" when there is no need for something to be set until initialization (it seems these can be used with (?) or (!))
Therefore, my questions are:
When do I use option 1 - a variable without ? and without !
When do I use "lazy"
I read "lazy" is often used for singletons - why?
I have the most experience in Java and C++ terms, if that helps with my background for answering.
Edit: Here's everything I found (The main issue was "Normal" vs "Implicitly Unwrapped Optionals":
"Normal" variables must be initialized: (a) On the same line, (b) in the same scope before usage (Usage means some operation with the object), (c) by the end of the init iff the variable is a field. Note: The scope of init is everything in the scope of the class AND not in the scope of functions within the class.
Printing an Implicitly Unwrapped Optional will print "nil", but using the variable's functions will throw a runtime exception. Meanwhile, using (at all, including print) a Normal variable will not allow the program to compile at all
The purpose of using ! over "" (Nothing) is (a) More leniency since the program will compile (and run correctly given the variable is actually initialized) and (b) Lets you not initialize everything at the very beginning. Note: It is a compile time error to have any field undeclared if it is a Normal variable.
Not exactly that.
All variables must be initialised before the first use, and all class/struct stored properties must be assigned value in respective initialiser. Optionals are not about being allowed uninitalised at some point, but about being allowed to contain no value, which is represented by nil, which is still perfectly an initialised stated for such variable. Therefore, if something can not be known at the moment of initialisation then that's probably where you will use some sort of an optional (e.g. delegate for a view).
Implicitly unwrapped optionals is a sort of shorthand for cases when a variable might be empty, but we are absolutely sure that when we will be really using it it will hold an actual value (typical example is a property in a view controller that holds reference to a view).
Forced unwrapping does not convert optional into implicitly unwrapped optional, instead it gives you a value that is there if it's there (i.e. if optional is not nil), and throws an exception if it's not.
Lazy properties are used in cases when you want to defer their initialisation to a later stage, when the property is actually being used for first time. Usual case is if you need to access an expensive resource to do that (load huge file from disk, download it via network, etc), especially so if there might be cases when such property is not going to be used at all (why loading it from the disk if we will not use it probably?).
let's see Apple's example
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
Residence instances have a single Int property called numberOfRooms, with a default value of 1. Person instances have an optional residence property of type Residence?.
If you create a new Person instance, its residence property is default initialized to nil, by virtue of being optional.
1. If you need default value for property to be nil - use optional. Using variable without ? and ! - like 'numberOfRooms' -
You can set the initial value of a stored property from within an initializer, as shown above. Alternatively, specify a default property value as part of the property’s declaration. You specify a default property value by assigning an initial value to the property when it is defined.
NOTE
If a property always takes the same initial value, provide a default
value rather than setting a value within an initializer. The end
result is the same, but the default value ties the property’s
initialization more closely to its declaration. It makes for shorter,
clearer initializers and enables you to infer the type of the property
from its default value. The default value also makes it easier for you
to take advantage of default initializers and initializer inheritance.
2. ! is used to access the value wrapped inside variable when it is not nil, and throws exeption otherwise. So, you can use ! in order to make mark for users of you class - 'this value will not be nil at the time you unwrap it'
3. Lazy variable is used when you want to init it later, not at the time of whole object creation but exactly at the time you ask getter for data. this is useful when property stores an array, for example:
lazy var players: [String] = {
var temporaryPlayers = [String]()
temporaryPlayers.append("John Doe")
return temporaryPlayers
}()
When should I use lazy initialization?
One example of when to use lazy initialization is when the initial value for a property is not known until after the object is initialized.
Short explanation:
A non optional variable has always a value and can never be nil.
The variable must be initialized in the init method or in the declaration line.
var a : String
var b = "bar"
init {
a = "foo"
}
An implicit unwrapped optional variable must not be initialized in the init method
or in the declaration line but is guaranteed to have always a value when it's used
var a : String!
func viewDidLoad() {
a = "Hello"
a += " world!"
}
An optional variable may have a value and is nil at declaration
var a : String? // = nil
A lazy variable is initialized later at the moment it's used the first time
class foo {
lazy var bar : String = {
return "Hello"
}()
}
I have created a class RootView with two properties, declared in different ways. Now I want to know what the difference between those two declarations is?
class RootView: UIViewController {
// MARK: - Variables
var rightMenu: RightMenu = RightMenu()
let right = RightMenu()
}
Please guide me about difference between right and rightMenu?
Both are of same type, but here below are few points that will tell when you need Type Annotation and when not.
Here are few concepts.
Your rightMenu is a variable, you reassign a value of same type at alter point, where as right is a constant, you can not reassign a new value.
Swift introduced type inference concept, where if you assign a value(literals) with out providing type, it will directly determine the the type for you. So need to provide explicitly type for it. Here your both rightMenu and right are of same type.
Ideally no need to provide explicitly type if you are assigning initial value to a variable at the time of declaration.
a) var myClass: MyClass!
Here you need to provide type, because no intial value is provided and you want to assign value to it at later point.
b) var myClass = MyClass()
Here no need, because you provided a initial value and Swift compiler will automatically determine the type for it.
In Swift providing/declaring type for a variable or constant after : symbol is called Type Annotation. For more details, see Apple documentation
The only difference is the mutability of those two variables. You can change rightMenu because it's mutable. However, right is not mutable. It means that right is a constant.
From the syntax prospectives, you don't necessarily to add :RightMenu when you declare rightMenu. Like you declare right, compiler will infer the object as type of RightMenu. But, when you want only to declare something without initializing it. You probably need to use :<type>? to tell the compiler that the type of this ivar and the value might be missing.
I have a very simple question on something that I may have misunderstood.
I have two UIViews "A" and "B". If I write :
let A = UIView() // Or something else
let B = A
and then I change properties of B (for exemple the frame), will the properties of A change too ?
I though not, but I was animating a view, so I had the initial view and the final view. I created a transition view like this :
let transitionView = finalView
and then I changed the properties of transitionView, the position of a label for exemple.
When I added the final view at the end of the animation, the label was at the new position.
Why ? Thanks
In swift types are split in 2 main categories:
reference types
value types
Classes are reference types; structs (which include arrays and dictionaries), basic data types (int, float, string, etc.), and enums are all value types.
A value type is always passed by value, which means when assigning to a variable or passing to a function/method, a copy of the original data is created. There's an exception to this rule: a function/method can use the inout modifier on a value type parameter to have it passed by reference.
Note that the compiler and the runtime usually do optimizations, so a copy is not always created unless strictly needed - what's important is that we, as developer, know that we are working on a copy and not on the original data.
A reference type is always passed by reference, which means when assigning it to a variable or passing it to a function/method, a reference to the data and not the data itself is assigned/passed.
UIView is a class, so when you create an instance, assign it to a variable, then assign that variable to another variable, the reference to the instance and not the instance itself is assigned. Both variables point to the same UIView instance. Any change made to the instance is visible to all variables referencing that instance.
Suggested reading: Classes and Structures
Because B and A are not two views. They are references to the same UIView object.
That, in turn, is because class instances are passed as reference types in Swift.
See now my little essay on this topic here: https://stackoverflow.com/a/27366050/341994
We used to declare property to pass data between classes as following:
.h file (interface file)
#property (nonatomic) double topSpeed;
.m file (implementation file)
#synthesize topSpeed;
Now there is no interface class, how to pass data between .swift classes ?
Swift provides no differentiation between properties and instance variables (i.e, the underlying store for a property). To define a property, you simply declare a variable in the context of a class.
A swift class is simply a ClassName.swift file.
You declare a class and properties as
class SomeClass {
var topSpeed: Double
var aStrProperty: String
var anIntProperty: Int
//Initializers and other functions
}
You access property values via dot notation. As of Xcode6 beta 4, there also are access modifiers (public, internal and private) in Swift. By default every property is internal. See here for more information.
For more information, refer to the Swift Programming Guide:
Stored Properties and Instance Variables
If you have experience with Objective-C, you may know that it provides
two ways to store values and references as part of a class instance.
In addition to properties, you can use instance variables as a backing
store for the values stored in a property.
Swift unifies these concepts into a single property declaration. A
Swift property does not have a corresponding instance variable, and
the backing store for a property is not accessed directly. This
approach avoids confusion about how the value is accessed in different
contexts and simplifies the property’s declaration into a single,
definitive statement. All information about the property—including its
name, type, and memory management characteristics—is defined in a
single location as part of the type’s definition.
Using Properties.
From the Swift Programming Guide:
Stored Properties and Instance Variables
If you have experience with Objective-C, you may know that it provides
two ways to store values and references as part of a class instance.
In addition to properties, you can use instance variables as a backing
store for the values stored in a property.
Swift unifies these concepts into a single property declaration. A
Swift property does not have a corresponding instance variable, and
the backing store for a property is not accessed directly. This
approach avoids confusion about how the value is accessed in different
contexts and simplifies the property’s declaration into a single,
definitive statement. All information about the property—including its
name, type, and memory management characteristics—is defined in a
single location as part of the type’s definition.
Properties in Objective-C correspond to properties in Swift. There are two ways to implement properties in Objective-C and Swift:
Synthesized/auto-synthesized properties in Objective C -- these are called "stored properties" in Swift. You simply declare it with var topSpeed : Double or let topSpeed : Double = 4.2 in a class declaration, exactly as you would declare a local variable in a function body. You don't get to specify the name of the backing instance variable because, well, there are currently no instance variables in Swift. You must always use the property instead of its backing instance variable.
Manually implemented properties in Objective-C -- these are called "computed properties" in Swift. You declare them in the class declaration like var topSpeed : Double { get { getter code here } set { setter code here } } (for readwrite properties), or var topSpeed : Double { getter code here } (for readonly properties).
It sounds like at least part of your question relates to communicating a given class's interface to other classes. Like Java (and unlike C, C++, and Objective-C), Swift doesn't separate the interface from the implementation. You don't import a header file if you want to use symbols defined somewhere else. Instead, you import a module, like:
import Foundation
import MyClass
To access properties in another class, import that class.
Stored Properties and Instance Variables
If you have experience with Objective-C, you may know that it provides two ways to store values and references as part of a class instance. In addition to properties, you can use instance variables as a backing store for the values stored in a property.
Swift unifies these concepts into a single property declaration. A Swift property does not have a corresponding instance variable, and the backing store for a property is not accessed directly. This approach avoids confusion about how the value is accessed in different contexts and simplifies the property’s declaration into a single, definitive statement. All information about the property—including its name, type, and memory management characteristics—is defined in a single location as part of the type’s definition.
From the Swift Programming Book:
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
I say : typealias is equivalent even more in swift for #synthesize
just look at this link : https://docs.swift.org/swift-book/ReferenceManual/Declarations.html