I have a struct with two variables inside property wrappers. One of the variables is supposed to be computed from the other. When I try to do this, I get the following error:
Cannot use instance member 'name' within property initializer; property initializers run before 'self' is available.
I tried assigning a temporary value to these variables, and then re-assigning them within a custom init()
function, but that doesn't seem to work ether. I made a simplified version of the code to see if I could isolate the issue.
import SwiftUI
struct Person {
@State var name: String = ""
@State var nameTag: NameTag = NameTag(words: "")
init(name: String) {
// not changing name and nameTag
self.name = name
nameTag = NameTag(words: "Hi, my name is \(name).")
}
}
class NameTag {
var words: String
init(words: String) {
self.words = words
}
}
var me = Person(name: "Myself")
// still set to initial values
me.name
me.nameTag.words
I noticed that when I changed nameTag to an @ObservedObject
, rather than @State
, it was able to be re-assigned correctly. Although I don't believe I can change name to @ObservedObject
. Could anyone tell me what I'm doing wrong?
To use property wrappers in initializers, you use the variable names with preceding underscores.
And with State, you use init(initialValue:).
struct Person {
@State var name: String
@State var nameTag: NameTag
init(name: String) {
_name = .init(initialValue: name)
_nameTag = .init( initialValue: .init(words: name) )
}
}
Here's what a @State
property really looks like, as your tear down levels of syntactic sugar:
name
_name.wrappedValue
$name.wrappedValue
_name.projectedValue.wrappedValue
You can't use the underscore-name outside of the initial type definition.