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?

2
  • 1
    Possible duplicate of How to initialize properties that depend on each other Commented Jan 27, 2017 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. Commented Jan 27, 2017 at 18:37

3 Answers 3

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);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Didn't know it was possible to assign a value to a constant later after declaring it. Thanks!
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.

Comments

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")]

4 Comments

As I mentioned in my question, I don't want to make it a var because I want songs to be immutable.
Then you can do this: let unmutableSongs: [Song] = [Song(title: "A")] And it works!
Yes it works, but as I mentioned I also want access to the individual song constants through their names.
So accessing like this: unmutableSongs[0].title Doesn't work for what you need?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.