Запутался в перечислении… Как мне изменить объекты, которые во время перечисления?

#objective-c

#objective-c

Вопрос:

Все еще новичок в Objective-C, и я запутался в перечислении…

Допустим, у меня есть NSArray из 8 объектов «Car», и у всех из них для свойства «paintColor» установлено значение «red. Я хочу перечислить через массив и установить для каждого свойства Car.paintColor значение «синий». Как мне это сделать?

 for (Car *car in myArray){
    car.paintColor = @"blue";  
}
  

Но тогда, если я это сделаю

 Car *testCar = [myArray objectAtIndex:2];

NSLog(@"The car color for 3rd object in myArray is %@", testCar.color);
  

Я все еще получаю «красный». Таким образом, кажется, что перечисление просто создает временный объект, но не изменяет фактический объект, который содержится в массиве.

Как правильно сделать то, что я пытаюсь сделать? У меня много ситуаций, когда я хочу перечислять через массив, но на самом деле изменяет элементы, которые находятся внутри массива

Спасибо

—РЕДАКТИРОВАТЬ

Хорошо, спасибо за эту информацию.. можете ли вы объяснить, почему это не работает?

У меня есть NSArray с именем «carsArray», настроенный как свойство, которое содержит три NSMutable строковых объекта («Buick», «Bronco», «Cadillac»).

Затем я делаю

 for (NSMutableString *car in myArray) {
    car = [NSMutableString stringWithFormat:@"test"];
}

NSMutableString *temp = [myArray objectAtIndex:2];
NSLog(@"third car is %@", temp);
  

NSLog говорит «Cadillac». Разве это не должно быть «тест»?

Комментарии:

1. Перечисление не должно создавать временные значения. Одна вещь, которую я заметил, это то, что при вызове NSLog вы считываете свойство color, но в enumerator вы устанавливаете свойство paintColor . Может быть, простой тип все портит?

2. Спасибо за эту информацию. Я добавил второй пример, и мне интересно, почему он не работает

Ответ №1:

Чтобы делать то, что вы хотите:

 for (NSMutableString *car in myArray) {
    [car setString:[NSMutableString stringWithFormat:@"test"]];
}
  

Базовое понимание указателей. Это не совсем перечисление, которое заставляет его работать таким образом.

 NSMutableString *car1 = [NSMutableString stringWithFormat:@"Cadillac"];
NSMutableString *car = car1;
[car setString:[NSMutableString stringWithFormat:@"Ford"]];
NSLog(@"car1 = %@", car1);

// Ford

car = [NSMutableString stringWithFormat:@"Buick"];
NSLog(@"car1 = %@", car1);

// Ford
  

Когда вы устанавливаете car = car1 , car является «псевдонимом» для car1. Вы можете установить свойства для car, и свойства будут установлены для car1. Вы можете вызывать такие методы, как setString на car, метод будет вызываться на car1. car и car1 являются указателями, они указывают на один и тот же объект.

Когда вы присваиваете новое значение car , оно просто делает его псевдонимом для другого объекта и больше не является тем же объектом, что и car1. Назначение не повлияет на car1, равно как и на любые средства доступа к свойствам или методы, которые вы выполняете в car после этого.

Перечисление эффективно выполняет car = myArray[0] car = myArray[1] , car = myArray[2] в свою очередь. (Сокращение: myArray[0] неверный синтаксис Objective-C.)

Ответ №2:

Быстрое перечисление не копирует объекты и не создает временные копии. NSArray — это массив указателей на объекты. Быстрое перечисление просто перебирает этот список указателей, и каждый раз через цикл вы получаете следующий указатель. Указатель указывает на тот же объект, на который указывает массив.

То, как вы меняете содержимое объекта в цикле быстрого перечисления, прекрасно.

Ваша проблема в другом месте (см. Комментарий Маттиа).