This question already has an answer here:
Swift- error: Variable 'self.___' used before being initialized
(1 answer)
Closed 3 years ago.
I have a Swift struct which has a title property. In my initializer, I can set the property as normal. If, however, I want to extract the logic for its value to another function, I get a compiler warning.
This works:
init(document: MyDocument) {
documentIdentifier = document.documentIdentifier
createDate = document.createDate
title = "A Title"
}
This fails:
title = generateTitle(forDocument: document)
The compiler says Variable 'self.title' used before being initialized. If I put a static setter just above this line, the error goes away. My generate function returns a non-optional value. What's the compiler grumpy about?
generateTitle is an instance method, but the instance itself isn't yet created before the initialiser returns and hence you cannot call any methods on it. If you really want to extract the setup code for title into a separate method and you aren't actually accessing any instance properties from that method, you can make it static and hence accessible even from the init.
Related
This question already has an answer here:
Did not understand process of initialize in swift programming
(1 answer)
Closed 6 months ago.
This is question for curiosity, How does init() function create instance?
Why when we assign values in init method makes instance? and How?
I feel like init() is just a method with assigning values without any return types but how!!! does it make return instance when we call it?
Anyone knows the answer? I read init() document but still not getting it. Anyone knows the answer?
Thank you for reading!
struct Rect {
var origin = Point()
var size = Size()
init() {}
}
let basicRect = Rect()
How is this working????????
The initializer is used in stored property:
Initializer is used in stored property to create an initial value.
Initializer is used in stored property to assign default property value within the property definition.
In Swift, init() is used to an initialize an instance.
This question already has answers here:
Difference between assigning the values in parameter list and initializer list
(2 answers)
Closed 2 years ago.
Flutter: The instance member'stars' can't be accessed in an initializer. Error
I asked the above question and received the following answer as the reason for the error.
reason : in dart you can't create a class level variable depends with
another variable
↑ Is there any explanation in the official Dart, Flutter document (or something similar)?
Or is it derived from the Dart constructor mechanism?
If so, I would like to understand how the constructor works, which is the reason for this error.
Is there any relevant part in the official Dart, Flutter documentation, etc.?
It is in fact due to Dart's constructor mechanism, specifically the order of execution during construction, as well as how Dart references instance variables within an object.
From the Instance Variables section of the Dart Language Tour:
If you initialize an instance variable where it is declared (instead of in a constructor or method), the value is set when the instance is created, which is before the constructor and its initializer list execute.
When you reference an instance variable in a Dart class via variableName there is an implied this reference to the instantiated object containing the variable. Due to the order of execution of Dart's object construction, this cannot reference the object during instance variable declaration because the object has not been created yet. Therefore, this.variableName and thus variableName (with implied this) cannot actually reference the instance variable.
This question already has answers here:
In Swift, what's the difference between calling UINavigationController() vs UINavigationController.init()?
(3 answers)
Closed 6 years ago.
What is difference between
URL.init(string: "")
and
URL(string: "")
Which is the better way?
The first way you stated uses an Initializer.
Initializers are called to create a new instance of a particular type. In its simplest form, an initializer is like an instance method with no parameters.
This means that they are used for:
To create an initial value.
To assign default property value within the property definition.
To initialize an instance for a particular data type 'init()' is used. No arguments are passed inside the init() function.
Therefore if you just want to use the data in the same instance you should use the first second method.
If you want to have the URL in anther instance and set it as a default value for your string you should use the first one.
But ultimately they will both do the same thing.
Is there difference ? And the effect of deinit ?
struct mark {
var mark: Int
}
struct mark {
var mark: Int
init(mark: Int) {
self.mark = mark
}
}
init is used to set initial values for properties on a struct or class type at the time it is created, before any other methods may be called on it and before it is passed as a parameter to other functions or methods.
In Swift, any non-optional properties must be set with initial values before init returns. Properties may be declared with initial values already, which excludes them from having to be set in an init method.
class types must have an init method implemented if there are any non-optional properties not already declared with initial values.
For struct types only, Swift will automatically generate an init method with parameters for each non-optional property that was not already declared with an initial value. You can optionally create any number of alternative init methods for the struct, as long as by the time each one returns, all non-optional properties have a value.
In your example, there is no difference between the init method created on the second line, and the automatically created init method provided for that struct type by Swift. But you could create alternate initializers that, for example, take a Double instead of an Int and then convert it internally before setting the mark property.
I think the key point to realize is that even when you do not specify an init method yourself, one still exists, as created automatically by Swift for struct types. So in both line one and line two of your example, an init method is being called (and they are essentially identical implementations). The only difference is that you wrote the init implementation in the second line, and the Swift compiler writes the init method in the first line.
deinitonly exists for class types, which are passed by reference and have memory management. Any deinit method you declare on a class you create will be called when there are no more references to that instance of the class and it will be released from memory. It's used to deregister from various observation patterns or otherwise clean up right before the instance is destroyed.
I just read that the init method can't be used as a value. Meaning:
var x = SomeClass.someClassFunction // ok
var y = SomeClass.init // error
Example found on Language reference
Why should it be like that? Is it a way to enforce language level that too dirty tricks come into place, because of some cohertion or maybe because it interferes with another feature?
Unlike Obj-C, where the init function can be called multiple times without problems, in Swift there actually is no method called init.
init is just a keyword meaning "the following is a constructor". The constructor is called always via MyClass() during the creation of a new instance. It's never called separately as a method myInstance.init(). You can't get a reference to the underlying function because it would be impossible to call it.
This is also connected with the fact that constructors cannot be inherited. Code
var y = SomeClass.init
would also break subtyping because the subtypes are not required to have the same initializers.
Why should it be like that?
init is a special member, not a regular method.
Beyond that, there's no reason that you'd ever need to store init in a variable. The only objects that could use that function in a valid way are instances of the class where that particular init is defined, and any such object will have already been initialized before you could possibly make the assignment.
Initializers don't have a return value. In order to assign it to something, it should be able to return something - and it doesn't.