-1

I have the following 2 classes Item & Items:

class Item{
    var name: String

    init(name: String) {
        self.name = name
    }
}

class Items{
    init(item: Item?) {
        self.item = item
    }
    var item: Item?
}

Then I try to do:

class MockData{        
    let item1 = Item(name: "XXX")
    let items : Items = Items(item: item1)
}

I get error at the second var: Cannot use instance member 'item1' within property initializer; property initializers run before 'self' is available

Why is that ?

user2816793
  • 19
  • 1
  • 5
  • Cannot reproduce, where exactly are you doing it? Is it inside a view controller or something similar? Does declaring `item1` as `lazy var` resolve the issue? – Ahmad F Apr 06 '20 at 21:31
  • @AhmadF I guess it's because you're using a playground. If you put both the variables inside a class then you'll run into the issue mentioned... – mfaani Apr 07 '20 at 02:05
  • @Honey correct, that's why the question should contain the code that reproduces the issue :) – Ahmad F Apr 07 '20 at 03:15
  • I have edited my question.. as you can notice. I am simply calling the constructor of Items from within different class. why its not working ? – user2816793 Apr 07 '20 at 15:35

2 Answers2

2

There is a good explanation already here: Property initializers run before 'self' is available

But you can't initialize properties that depend on each other at the top level of a class or struct.

struct dummy {
    let item1: Item
    let items1 : Items = Items(item: item1)

    init(name: String) {
        item1 = Item(name: name)
        items1 = Items(item: item1)
    }

}
HalR
  • 11,411
  • 5
  • 48
  • 80
  • That `lazy var` can be `let`, as long as you don't use the property initializer. (I think maybe you're trying to combine two examples into one?) –  Apr 07 '20 at 02:11
  • Thanks @Jessy I got sloppy after false starting in a different (and bad) solution. – HalR Apr 07 '20 at 16:24
0

You cannot execute code on the top level of a class which refers to self.

What you can do is to create Item in the same line

class MockData {
    let items = Items(item: Item(name: "XXX"))
}
vadian
  • 274,689
  • 30
  • 353
  • 361