S.Murugan
S.Murugan

Reputation: 21

update array index but its changing all index in IOS

here i am trying to update particular value in index but its updating all the index

class salarty  {

var sal_id                        :String = ""
var sal_amount             :String = ""
var sal_iScreated          :Bool = false

init(sal_id : String, sal_amount : String, sal_iScreated: Bool){

   self.sal_id                =  sal_id
   self.sal_amount     =  sal_id
   self.sal_iScreated =  sal_id

}
}

class Employee {

    let id: Int, firstName: String, lastName: String
    var salaryArray  :[salarty]  = [salarty]()


    init(id: Int, firstName: String, lastName: String, salaryArray: [salarty]) {
        self.id = id
        self.firstName = firstName
        self.lastName  = lastName
        self.salaryArray = salaryArray
    }
     }


array_SalaryDetails.append(salarty(sal_id : "2", sal_amount : "3000", sal_iScreated: false))

let employeeArray = [
    Employee(id: 1, firstName: "Jon", lastName: "Skeet",salaryArray :array_SalaryDetails),
    Employee(id: 2, firstName: "Darin", lastName: "Dimitrov",salaryArray :array_SalaryDetails),
    Employee(id: 4, firstName: "Hans", lastName: "Passant",salaryArray :array_SalaryDetails)
]

here i tried with some code its not working

Method 1 :

var model  = Employee[(indexPath?.section)!].salaryArray
        let model2 = model[(indexPath?.row)!]
        model = model.map{
            let mutableval = $0
            if $0.sal_id == model2.sal_id {
                mutableBook.sal_iScreated = !model2.sal_iScreated
            }
            return mutableval
        }

Method 2 :

    let model  = array_Main[(indexPath?.section)!].serviceArray
    let model2 = model[(indexPath?.row)!]

    model2.service_isSelected = !model2.service_isSelected

Upvotes: 0

Views: 82

Answers (1)

Sandeep Bhandari
Sandeep Bhandari

Reputation: 20379

Thats because in Swift instance of class are passed by reference and not by value.

So the salary array you created and passed to multiple Employee object they eventually had reference to same salary objects . So changing value of salary in any array in any Employee object would reflect change in all Employee objects

Two possible solutions:

Solution 1: Preferred solution

Change salarty to be struct and not class and if possible change the spelling of salary as well :P

struct salarty  {
        
        var sal_id                        :String = ""
        var sal_amount             :String = ""
        var sal_iScreated          :Bool = false
        
        init(sal_id : String, sal_amount : String, sal_iScreated: Bool){
            
            self.sal_id                =  sal_id
            self.sal_amount     =  sal_id
            self.sal_iScreated =  sal_iScreated
            
        }
    }

Solution 2:

Create a deep copy of salary array for each Employee before assigning.

class salarty : NSObject, NSCopying  {
    func copy(with zone: NSZone? = nil) -> Any {
        let copy = salarty(sal_id: self.sal_id, sal_amount: self.sal_amount, sal_iScreated: self.sal_iScreated)
        return copy
    }
    
    
    var sal_id                        :String = ""
    var sal_amount             :String = ""
    var sal_iScreated          :Bool = false
    
    init(sal_id : String, sal_amount : String, sal_iScreated: Bool){
        
        self.sal_id                =  sal_id
        self.sal_amount     =  sal_id
        self.sal_iScreated =  sal_iScreated
        
    }
}

for each employee you can create a new array using either

    array_SalaryDetails.append(salarty(sal_id : "2", sal_amount : "3000", sal_iScreated: false))
    //salary array copy for first employee
    var firstEmployeearrayCopy = [salarty]()
    for salary in array_SalaryDetails {
        firstEmployeearrayCopy.append(salary.copy() as! salarty)
    }
    Employee(id: 1, firstName: "Jon", lastName: "Skeet",salaryArray : firstEmployeearrayCopy)

    //salary array copy for second employee
    var secondEmployeearrayCopy = [salarty]()
    for salary in array_SalaryDetails {
        secondEmployeearrayCopy.append(salary.copy() as! salarty)
    }
    Employee(id: 2, firstName: "Darin", lastName: "Dimitrov",salaryArray :secondEmployeearrayCopy)

or you can create array again n again for each employee.

In swift Array is passed by value but the objects (instance of class) in array will still be passed by reference as a result you will have to do all these workarounds :)

Piece of Advice:

Class names should start with capital letter. Only variable names follow camel casing.

Hope it helps

Upvotes: 2

Related Questions