0

When I try to create the below songs array, I get the error:

"Cannot use instance member 'song' within property initializer; property initializers run before 'self' is available"

class ViewController: UIViewController {
    struct Song {
        let title: String
    }
    let song = Song(title: "A")
    let songs = [song]
}

I can move let songs = [song] into viewDidLoad(), but then I can't access songs from other functions. I can change let to var and then change songs in viewDidLoad() to my array of songs, but then I've created a mutable array when I want it to be immutable.

How do I get an immutable array of songs available to all functions and still have each individual song available in its own constant as well?

at.
  • 50,922
  • 104
  • 292
  • 461
  • 1
    Possible duplicate of [How to initialize properties that depend on each other](http://stackoverflow.com/questions/25854300/how-to-initialize-properties-that-depend-on-each-other) – rmaddy Jan 27 '17 at 18:28
  • That question is a bit of a different question and answers don't apply. I want an immutable array available to other functions. And I want the individual elements accessible by name too. – at. Jan 27 '17 at 18:37

3 Answers3

1

You can achieve this by creating your songs array during initialization.

class ViewController: UIViewController {
    struct Song {
        let title: String
    }
    let song = Song(title: "A")
    let songs : [Song]

    required init?(coder aDecoder: NSCoder) {
        self.songs = [self.song]
        super.init(coder: aDecoder);
    }
}
Alex
  • 541
  • 5
  • 19
  • Didn't know it was possible to assign a value to a constant later after declaring it. Thanks! – at. Jan 28 '17 at 05:45
1

Given that song is a constant, a simple solution would be just to make it a static property:

class ViewController: UIViewController {
    struct Song {
        let title: String
    }
    static let song = Song(title: "A")
    let songs = [song]
}

If you need to access it within any instance methods, you can just say ViewController.song.

Hamish
  • 78,605
  • 19
  • 187
  • 280
0

For making an array of Song Type and add song you should:

var songs = [Song]()

And on view Did Load:

songs.append(song)

So it would be:

class ViewController: UIViewController {
    struct Song {
        let title: String
    }
    let song = Song(title: "A")
    var songs = [song]

   override func viewDidLoad() {
        super.viewDidLoad()
        songs.append(song)

    }
}

Another Option to maintain it unmutable:

let unmutableSongs: [Song] = [Song(title: "A")]
Mago Nicolas Palacios
  • 2,501
  • 1
  • 15
  • 27