Странно для циклов, с которыми я не знаком: "for (id * in *)"

Я прошу прощения, если этот вопрос чрезвычайно прост, но я погуглил как сумасшедший и не могу найти подходящего объяснения, что это такое.

for (id line in self.lines){
    [linesCopy addObject:[line copyWithZone:zone]];
}

Я только учусь Objective-C, и это форма for петля, которую я никогда раньше не видел. Я знаком с простым

for (int x = 1, x < 10, x++)

стиль for петля.

4 ответа

Решение

Из основных компетенций Какао: Перечисление:

Быстрое перечисление

Несколько классов Какао, включая классы коллекции, принимают NSFastEnumeration протокол. Он используется для извлечения элементов, содержащихся в экземпляре, с использованием синтаксиса, аналогичного синтаксису стандартного цикла C for, как показано в следующем примере:

NSArray *anArray = // get an array;
for (id element in anArray) {
    /* code that acts on the element */
}

Как следует из названия, быстрое перечисление более эффективно, чем другие формы перечисления.

Если ты не знал, id является типом Objective C, который в основном означает "указатель на любой объект Objective C". Обратите внимание, что указатель id встроен в него; Вы обычно не хотите говорить id *,

Если вы ожидаете элементы anArray скажем, определенного класса MyObject, вы можете использовать это вместо:

for (MyObject *element in anArray) {
    /* code that acts on the element */
}

Однако ни компилятор, ни среда выполнения не проверят, что элементы действительно являются экземплярами MyObject, Если элемент anArray не является примером MyObjectвы, вероятно, в конечном итоге попытаетесь отправить ему сообщение, которое он не понимает, и получите исключение, не распознаваемое селектором.

Это называется forin цикл, также называемый быстрым перечислением. В основном, синтаксис:

for (SomeObjectIAmExpecting *localVariableName in anArrayOfObjects)
{
    if (![localVariableName isKindOfClass:[SomeObjectIAmExpecting class]]) continue; //To avoid errors.
     //do something to them
}

Это утверждение, которое можно использовать с классами, которые соответствуют NSFastEnumeration протокол. Когда у вас есть это, руководство по программированию Objective-C предлагает вам его использовать. Посмотрите здесь. Это способ перебора коллекции без традиционного for (int i = 0; i < length; ++i) синтаксис.

Имейте в виду, что он обычно не поддерживает удаление и вставку элементов во время итерации по этому пути (также с использованием обычного for Зацикливайтесь на индексах нужно в любом случае позаботиться).

В основном все стандартные коллекции поддерживают этот способ итерации.

Это сокращенный эквивалент этой распространенной формы:

for (int i = 0; i < [self.lines count]; i++) {
    id line = [self.lines objectAtIndex:i];
    // ...
}

Это настолько распространенная идиома зацикливания (обход некоторой коллекции, массива, набора и т. Д. За раз), что она превращается в сокращенную форму, такую ​​как эта, называемая "быстрое перечисление".

Фактически, в своей внутренней реализации, это на самом деле немного быстрее, чем делать это самостоятельно, поэтому предпочтительнее как для ясности, так и для производительности.

Другие вопросы по тегам