3

I am new to Swift and i'm trying to mess around with some UITableViews and Arrays.

I have an array of type [Day], named daysArray. I'm initiating the array in ViewDidLoad(), daysArray has 7 "days" in it.

Also, I have UITableView, which is being populated with the daysArray. When I'm trying to change one day (one element in the array), the whole daysArray days are changed and consequently, all cells in the UITableView are the same.
This is so peculiar, I really don't know what is wrong (:

The 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
        }
    }
}

The code that seems to be problematic is:

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 very peculiar... Thank you for just reading my question, and also for answering of course (:

3 Answers 3

3

In your loop you instantiate objects with the same reference. You have to replace :

let generalDay: Day = someDay

by this :

let generalDay = Day(dayDict: GeneralDayDict)

Then you will be able to change attributes of generalDay individually

Sign up to request clarification or add additional context in comments.

Comments

1

Classes in Swift are passed by reference. Meaning each item in your array points to the same thing. So when you update one, you update them all.

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

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

2 Comments

or create a new object for each append: daysArray.append(Day(dayDict: GeneralDayDict))
I'll read about it, but for now, Maxime answer below seemed to fix my issue. Thank you anyway!!!!
1

Set the class of Day to be NSObject

class Day : NSObject {

}

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

    }

then just append the copy of the generalDay Object

Hope it helps!!

Comments

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.