#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 — это массив указателей на объекты. Быстрое перечисление просто перебирает этот список указателей, и каждый раз через цикл вы получаете следующий указатель. Указатель указывает на тот же объект, на который указывает массив.
То, как вы меняете содержимое объекта в цикле быстрого перечисления, прекрасно.
Ваша проблема в другом месте (см. Комментарий Маттиа).