Nathanael Tse
Nathanael Tse

Reputation: 363

Store class data in an array in swift 4 that is not modifiable

I am creating characters and want to store them in an array. The problem occurs when I want to store the second character, because it overwrites the data of the first one - it seems like the variable is stored instead of a mirror of the content:

Code in Playground:

import UIKit

class character {

    var name: String
    var owner: String

    init() {
        name = "Frodo"
        owner = "Ben"
    }
    func random() {
        name = "Gollum"
        owner = "Hans"
    }
}

var CharacterArray: [character] = []

let testchar = character.init()

CharacterArray.append(testchar)

testchar.random()

CharacterArray.append(testchar)

When I look into the first appended array, ("Frodo, Ben") is stored. When I look after the second append both entries are ("Gollum", "Hans").

How can I ensure that the data stored in the array is an individual value? I believe I have a conceptional error here.

Please advise.

Thanks!

Upvotes: 1

Views: 222

Answers (1)

Lawliet
Lawliet

Reputation: 3499

That's not the problem of Swift 4, but the difference between reference and value types in Swift. You can change your character from class to struct, and you will see the difference.

struct MyCharacter {
    var name: String
    var owner: String

    init() {
        name = "Frodo"
        owner = "Ben"
    }

    mutating func random() {
        name = "Gollum"
        owner = "Hans"
    }
}

var myArray: [MyCharacter] = []

var csVal = MyCharacter()
myArray.append(csVal)
csVal.random()
myArray.append(csVal)

for character in myArray {
    print(character.name)
}

One more thing is you should capitalise the first letter of the Class/Struct name and change the first letter of your variable name to lower case. Check this out for more information of Swift name conventions.


If you still want to keep your design, a work around is to return a new Character from your random function.

import UIKit

class Character {
    var name: String
    var owner: String

    init() {
        name = "Frodo"
        owner = "Ben"
    }

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

    func random() -> Character {
        return Character(name: "Gollum", owner: "Hans")
    }
}

var characterArray: [Character] = []

let testchar = Character()
characterArray.append(testchar)
let random = testchar.random()
characterArray.append(random)

for character in characterArray {
    print(character.name)
}

Upvotes: 1

Related Questions