self' used before all stored properties are initialized
In this case I would suggest you to make the property a variable but hiding it (make it seem like a constant) through a computed property:
class Country {
let name: String
private var _capitalCity: City!
var capitalCity: City {
return _capitalCity
}
init(name: String, capitalName: String) {
self.name = name
self._capitalCity = City(name: capitalName, country: self)
}
}
self' used before all stored properties are initialized in struct
Instead defining your getRandom as an instance method, define it as a static one, then reference it by a type name (CurrentData
) or Self
struct CurrentData {
var size: (x: Int, y: Int)
var location: (x: Int, y: Int)
init(size: (x: Int, y: Int)) {
self.size = size
location = (Self.getRandom(size.x), Self.getRandom(size.y))
}
private static func getRandom (_ value:Int) -> Int {
Int.random(in: 0...value-1)
}
}
Other solution is to define your location
property as a lazy one, then the self
is accessible and the location will be executed only once and after being called in the code.
struct CurrentData {
var size: (x: Int, y: Int)
lazy var location: (x: Int, y: Int) = {
(getRandom(size.x), getRandom(size.y))
}()
init(size: (x: Int, y: Int)) {
self.size = size
}
private func getRandom (_ value:Int) -> Int {
Int.random(in: 0...value-1)
}
}
Struct initialization in SwiftUI: 'self' used before all stored properties are initialized
You shouldn't create @ObservedObject
values in your initializer. Doing so leads to bugs, because you'll create new instances every time the view is recreated. Either jobsViewModel
and categoriesViewModel
should be passed as arguments to init
, or you should be using @StateObject
for those properties.
But anyway, you actually asked: why can't we use $jobFilter
before initializing jobsViewModel
?
Let's start by simplifying the example:
struct JobsTab: View {
@State var jobFilter: String
var jobFilterBinding: Binding<String>
init() {
jobFilter = ""
jobFilterBinding = $jobFilter
// ^ 'self' used before all stored properties are initialized
}
var body: some View { Text("hello") }
}
So, what's going on here? It'll help if we “de-sugar” the use of @State
. The compiler transforms the declaration of jobFilter
into three properties:
struct JobsTab: View {
private var _jobFilter: State<String>
var jobFilter: String {
get { _jobFilter.wrappedValue }
nonmutating set { _jobFilter.wrappedValue = newValue }
}
var $jobFilter: Binding<String> {
get { _jobFilter.projectedValue }
}
var jobFilterBinding: Binding<String>
init() {
_jobFilter = State<String>(wrappedValue: "")
jobFilterBinding = $jobFilter
// ^ 'self' used before all stored properties are initialized
}
var body: some View { Text("hello") }
}
Notice now that $jobFilter
is not a stored property. It is a computed property. So accessing $jobFilter
means calling its “getter”, which is a method on self
. But we cannot call a method on self
until self
is fully initialized. That's why we get an error if we try to use $jobFilter
before initializing all stored properties.
The fix is to avoid using $jobFilter
. Instead, we can use _jobFilter.projectedValue
directly:
struct JobsTab: View {
@State var jobFilter: String
var jobFilterBinding: Binding<String>
init() {
jobFilter = ""
jobFilterBinding = _jobFilter.projectedValue
}
var body: some View { Text("hello") }
}
SwiftUI: 'self' used before all stored properties are initialized
If I understand the question correctly it sounds like you want the view to track some vpnState
class from your view and you're attempting to pass references from the view to the controller object, but that's backwards of how SwiftUI is designed.
Fundamentally you should view Views as read-only objects that are updated behind the scenes by the framework. You lock them onto a property or object to observe and when that thing changes the view is automatically updated with the new value.
@State
variables are intended for use strictly within your views, like for use with an animation or some other intermediate state completely within the View. In this instance the Swifty thing to do would be to use a @ObservedObject
or @EnvironmentObject
to watch the state of the object for you.
As to why self
is a "different" object when you use it that is because a struct
is a value type not a reference type. It is destroyed and recreated by Swift each time it is change. It is not "updated" in the sense that values are changed on the object.
self' used before all stored properties are initialized error - @State - extension - second file
Here the solution with @binding:
// ListCell.swift
import SwiftUI
struct ListCell: View {
@Binding var name: String
var count: Int
var body: some View {
HStack {
Text(name)
Text(": \(count)")
}
}
}
// ListCell+Ext.swift
import SwiftUI
extension ListCell {
init(name: Binding<String>) {
self.init(name: name, count: 0)
}
}
Initializing 2 variables in init(): 'self' used before all stored properties are initialized
Binding as a property (hidden) has _ (underscore), so you have to initialize it as
init(showSurvey: Binding<Bool>) {
self.customerVM = BuildCustomerViewModel()
self._showSurvey = showSurvey // << this !!
}
Use of 'self' in method call 'f' before all stored properties are initialized
It doesn't mean that if you haven't written self
with function call f
then it will not reference to self
as of f
is still instance method, so with init
it must be called after all the instance properties are initialized means after the the instance of class is initialized. So simply call f()
after you initialized
the instance property a
.
class A {
var a: String
init(a: String) {
self.a = a
f()
}
func f() {
print("HeHe")
}
}
Related Topics
Do Swift Inner Classes Have Access to Self of Outer Class
Add "For In" Support to Iterate Over Swift Custom Classes
How to Convert Timeinterval into Minutes, Seconds and Milliseconds in Swift
How to Override Trait Collection for Initial Uiviewcontroller? (With Storyboard)
How to Get Directory Size with Swift on Os X
Upvote/Downvote System Within Swift via Firebase
Override Func Error in Swift 2
Building Pure Swift Cocoa Touch Framework
Swift - Unit Testing Private Variables and Methods
A Swift Protocol Requirement That Can Only Be Satisfied by Using a Final Class
Xcode 7 Compile Error: "Command Failed Due to Signal: Segmentation Fault: 11"