67

Seems like I'm having a problem with something that shouldn't be the case... But I would like to ask for some help.

There are some explanations here on the Stack I don't get.

Having two simple classes where one refers to another, as per below:

class User {
  lazy var name: String = ""
  lazy var age: Int = 0

  init (name: String, age: Int) {
      self.name = name
      self.age = age
  }
}

class MyOwn {
  let myUser: User = User(name: "John", age: 100)
  var life = myUser.age 
  //Cannot use instance member 'myUser' within property initializer
  //property initializers run before 'self' is available
}

I get the commented compile error. May someone please tell me what should I do to solve the case?

Alexander Farber
  • 21,519
  • 75
  • 241
  • 416
RafalK
  • 749
  • 2
  • 7
  • 13

3 Answers3

60

As correctly pointed out by vadian you should create an init in such scenarios:

class MyOwn {
    let myUser: User
    var life: Int

    init() {
        self.myUser = User(name: "John", age: 100)
        self.life = myUser.age 
    }
}

You can't provide a default value for a stored property that depends on another instance property.

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
24

You should declare life like this:

lazy var life:Int = {
    return self.myUser.age
}()

Because you are trying to initialise one property(variable) with another during initialisation process. At this time variables are not available yet.

Eugene Laminskiy
  • 594
  • 2
  • 11
  • Should work fine, but isn't using `lazy` for that an overkill? ;-) – Paulo Mattos Apr 21 '17 at 20:02
  • 3
    @PauloMattos The code architecture presented in your answer is more acceptable, at least for me. But I can not say why a person needed the architecture that he is trying to implement. I just showed him how to do it without compilation errors and explained what was his mistake – Eugene Laminskiy Apr 21 '17 at 20:07
0

What worked for me is turning the variable into a computed property

// Previous declaration
var temperatureString = String(format:"%.1f", temperature) // "Cannot use instance member 'temperature' within property initializer; property initializers run before 'self' is available" 

// Computed Property
var temperatureString : String { 
   return String(format:"%.1f", temperature)
}
Santi iOS
  • 61
  • 7