Spec-Zone.ru › GCC 15

9.9.4 Протокол быстрого перечисления

Чтобы ваш собственный объект коллекции можно было использовать с быстрым перечислением, необходимо реализовать в нём метод

- (unsigned long) countByEnumeratingWithState: (NSFastEnumerationState *)state
                                      objects: (id *)objects
                                        count: (unsigned long)len;

где NSFastEnumerationState должен быть определён в вашем коде следующим образом:

typedef struct
{
  unsigned long state;
  id            *itemsPtr;
  unsigned long *mutationsPtr;
  unsigned long extra[5];
} NSFastEnumerationState;

Если в вашем коде не определён NSFastEnumerationState, компилятор автоматически заменит NSFastEnumerationState * на struct __objcFastEnumerationState *, причём этот тип будет неявно определён компилятором точно так же. Это может вызвать путаницу, поэтому мы рекомендуем вместо этого определить NSFastEnumerationState (как показано выше).

Во время быстрого перечисления метод многократно вызывается для получения пакетов объектов. При каждом вызове метода следует получать следующий пакет объектов.

Метод возвращает количество объектов в текущем пакете; оно не должно превышать len — максимальный размер пакета, запрошенный вызывающим кодом. Сам пакет возвращается в поле itemsPtr структуры NSFastEnumerationState.

Для упрощения возврата объектов массив objects представляет собой C-массив, заранее выделенный вызывающим кодом (в стеке) размером len. Во многих случаях можно поместить объекты, которые нужно вернуть, в этот массив objects, а затем выполнить itemsPtr = objects. Но это не обязательно: если в вашей коллекции уже есть возвращаемые объекты в виде какого-либо C-массива, их можно вернуть оттуда.

Поля state и extra структуры NSFastEnumerationState позволяют объекту коллекции отслеживать состояние перечисления. В простой реализации на основе массива state может хранить индекс последнего возвращённого объекта, а extra можно не использовать.

Поле mutationsPtr структуры NSFastEnumerationState используется для отслеживания изменений. Оно должно указывать на число; перед обработкой каждого объекта цикл быстрого перечисления проверяет, не изменилось ли это число. Если оно изменилось, значит, произошла модификация и быстрое перечисление будет прервано. Поэтому mutationsPtr может указывать на некоторый номер версии коллекции, который увеличивается на единицу при каждом изменении (например, при добавлении или удалении объекта). Или, если вас устраивает менее строгая проверка изменений, оно может указывать на количество объектов в коллекции или на другое значение, позволяющее приблизительно проверить, не была ли коллекция изменена.

Наконец, обратите внимание, что аргумент len и возвращаемое значение объявлены имеющими тип unsigned long. Их также можно было бы объявить имеющими тип unsigned int, и всё равно всё работало бы.

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-15.3.0/gcc/Fast-enumeration-protocol.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API