at.
at.

Reputation: 52540

How to create an immutable array of struct instances as an instance variable in Swift?

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?

Upvotes: 0

Views: 129

Answers (3)

Alex
Alex

Reputation: 541

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);
    }
}

Upvotes: 1

Hamish
Hamish

Reputation: 80811

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.

Upvotes: 1

Mago Nicolas Palacios
Mago Nicolas Palacios

Reputation: 2591

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

Upvotes: 0

Related Questions