Changing one element in an array changes all elements of the array

I am new to Swift and I am trying to tinker with some UITableViews and arrays.

I have an array of type [Day]

named daysArray

. I am initiating an array in ViewDidLoad()

, daysArray

has 7 "days" in it.

Also, I have UITableView

one that is populated with daysArray

. When I try to change one day (one element in the array), all the daysArray

days change, and hence all the cells in the UITableView

same.
It's so weird, I really don't know what's wrong (:

Day class:

import Foundation

class Day {

    private var _name: String!
    private var _starts: Double!
    private var _ends: Double!

    var name: String! {
        get {
            if _name == nil {
                _name = "Sunday"
            }
            return _name
        }
        set {
            _name = newValue
        }
    }

    var starts: Double! {
        get {
            if _starts == nil {
                _starts = 8.00
            }
            return _starts
        }
        set {
            _starts = newValue
        }
    }
    var ends: Double! {
        get {
            if _ends == nil {
                _ends = 20.00
            }
            return _ends
        }
        set {
            _ends = newValue
        }
    }

    init(dayDict: Dictionary<String, AnyObject>) {
        if let dictName = dayDict["name"] as! String! {
            self._name = dictName
        }
        if let dictIsWorking = dayDict["isWorking"] as! Bool! {
            self._isWorking = dictIsWorking
        }
        if let dictStarts = dayDict["starts"] as! Double! {
            self._starts = dictStarts
        }
        if let dictEnds = dayDict["ends"] as! Double! {
            self._ends = dictEnds
        }
    }
}

      

Code that seems problematic:

import UIKit


let GeneralDayDict: [String : AnyObject] = ["name" : "Sunday" as AnyObject, "starts": 8.00 as AnyObject, "ends" : 20.00 as AnyObject]
let someDay: Day = Day(dayDict: GeneralDayDict)



class ViewController: UIViewController {

    var daysArray: [Day]! = []

    override func viewDidLoad() {
        super.viewDidLoad()

        for i in 0...6 {
            let generalDay: Day = someDay
            daysArray.append(generalDay)

        }
        changeArray()

        // Do any additional setup after loading the view, typically from a nib.
    }

    func changeArray() {
        daysArray[5].starts = 6.00
        for day in daysArray {
            print("Each day in the array starts at: ", day.starts)
        }


    }
}

      

The print command in changeArray prints this:

Each day in the array starts at:  6.0
Each day in the array starts at:  6.0
Each day in the array starts at:  6.0
Each day in the array starts at:  6.0
Each day in the array starts at:  6.0
Each day in the array starts at:  6.0
Each day in the array starts at:  6.0

      

As I said, very strange ... Thanks for just reading my question and also of course the answer (:

+3


source to share


3 answers


In your loop, you create objects with the same reference. You must replace:

let generalDay: Day = someDay

      

:



let generalDay = Day(dayDict: GeneralDayDict)

      

Then you will be able to change the generalDay attributes separately

+3


source


Classes in Swift are passed by reference. The value of each element in your array points to the same thing. So when you upgrade one, you upgrade them all.

Try it with a struct instead of using a class and you will see the difference.



See the Documentation for a better explanation and arguments behind this.

+1


source


Set the class of the day as NSObject

class Day : NSObject {

}

 for i in 0...6 {
        let generalDay: Day = someDay
        daysArray.append(generalDay.copy())

    }

      

then just add a copy of the CommonDay object

Hope it helps!

+1


source







All Articles