2

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?

Evan93
  • 155
  • 11
  • Perhaps this discussion of [State and ObservedObject](https://stackoverflow.com/questions/59538786/what-is-the-difference-between-state-and-observedobject-can-they-both-be-used) can help aid your understanding of what they mean, and how to use them. – Sean Skelly Apr 01 '20 at 22:58

2 Answers2

3

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.

  • How are underscores "_" being used in this case? I haven't seen them be used like that before. Thanks! – Evan93 Jun 24 '20 at 23:45
0

This also happened when you are building the app for old OS iPhone for those Apple is not giving updates because things becomes deprecated. use for example

if #available(iOS 16.0, *) {

 } else {
     // Fallback on earlier versions
 }

on each single line where this warning is being shown. Note: Don't use it in the start of the body of class or struct use it where its needed.