I am not able to modify my model class variable even using mutating func keyword in a method?
So basically I have wrapped my problem in a very easy way I have a class Car that has 3 variable id, start, and modelNo
After that initialize an empty Car model array and then I want to show 10 cars, creating a range for loop which iterates 1...10, initializing the Car model class and appending it to original cars array.
There is a check for first 5 cars id will be 0 and last 5 cars id will be 1
I want a filter in which same id's last car will start so I have created a method filtered and modifying the start variable but not able to modify it. Can you please help me what I am doing wrong?
Please see my complete code and copy paste it to the playground.
struct Car {
var id = 0
var start = false
var modelNo: String
init(start: Bool, id: Int, model: String) {
self.start = start
self.id = id
self.modelNo = model
}
mutating func startCar(status: Bool) {
start = status
}
}
var arrCars:[Car] = [Car]()
for i in 1...10 {
let md = Car(start: false, id: i <= 5 ? 0 : 1, model: "Model\(i)")
arrCars.append(md)
}
private func filtered() {
for item in arrCars {
let filteredItems = arrCars.filter { $0.id == item.id }
if filteredItems.count > 0 {
if var lastItem = filteredItems.last {
print("Will start \(lastItem.modelNo)")
lastItem.startCar(status: true)
}
}
}
let cars = arrCars.filter { (car) -> Bool in
car.start == true
}
print(cars.count)
}
filtered()
Any help will be appreciated.
Creating a
mutatingfunction on a struct doesn't change the value semantics of structs. As soon as a struct instance is mutated, a copy is made.You say:
So,
lastItemcontains an instance of a car you are going to start. Under the covers this is the same instance of the car that is infilteredItems, which is the same instance that is inarrCars. But, as soon as you mutate theCarinlastItem, a copy is made, solastItemno longer has the same instance as the one inarrCars.filteredItemsandarrCarsstill contain the original, unalteredCarinstance.You can change
Carto be aclassrather than astructso that it has reference semantics to get the behaviour you want.The other option is to modify the instance in place; something like
arrCars[0].startCar(status: true). To do this you will need to get an array containing the indicies of the cars you want to start rather than the cars themselves:However, where a model object requires mutability or is stateful, a struct is probably not suitable.