У меня есть класс, и я хочу, чтобы мой класс подтвердил NSFastEnumeration Protocol. Я прочитал документацию, но это не совсем понятно. Может кто-нибудь, пожалуйста, скажите мне, что должен вернуть метод протокола и как он работает?
Как реализовать протокол NSFastEnumeration?
Ответ 1
Apple FastEnumerationSample показывает вам, что делать, но вот разбивка.
Единственный метод NSFastEnumeration
, countByEnumeratingWithState:objects:count:
, возвращает куски коллекции. Он выполняется всякий раз, когда требуется больше элементов, пока не будет указано, что больше нет элементов, возвращающих 0. Блок передается как массив C из id
s.
Внутри метода параметр state
содержит большинство (если не все) данных, которые вы будете использовать. Вам нужно установить state->itemsPtr
и обновить state->state
с помощью каждого отдельного вызова countByEnumeratingWithState:objects:count:
. Здесь краткое описание каждого поля NSFastEnumerationState
:
-
state
: представляет собой позицию в последовательности, повторяющейся. Для индексированных коллекций это будет индекс. Для связанных списков это может быть указатель node. Для других типов это может быть более сложный тип (например, для дереваstate->state
может быть NSMutableArray, используемым в качестве стека для хранения узлов). КогдаcountByEnumeratingWithState:objects:count:
сначала вызывается,state->state
равно 0; проверьте это условие для инициализации структурыstate
. -
itemsPtr
: элементы в куске; указывает на массив C изid
s. Cocoa будет зацикливаться на этом массиве, привязывая каждый элемент в свою очередь к переменной, названной в цикле for-in. -
mutationsPtr
: для изменяемых коллекций, используемых для указания того, что коллекция изменилась с момента последнего вызоваcountByEnumeratingWithState:objects:count:
. Как правило, вы устанавливаете это один раз при инициализации состояния. Мутаторы коллекции увеличивают значение, на которое это указывает. Cocoa сравнивает значение, возвращаемоеcountByEnumeratingWithState:objects:count:
, с значением из предыдущего вызова; если они отличаются, Cocoa выдаст исключение. -
extra
: вы можете использовать это для хранения дополнительных данных.
Вы можете установить state->state
и любой элемент state->extra
на все, что пожелаете; они предоставляются исключительно для вашего удобства и не влияют на Cocoa. state->itemsPtr
, *state->mutationsPtr
и значение, возвращаемое методом, однако, влияет на Cocoa.
Как и для двух других параметров метода, stackbuf
- это массив, который Cocoa предоставляет для хранения элементов. Его использование необязательно, но если вы его не используете, вам нужно будет выделить место для хранения state->itemPtr
. Если вы используете его, установите state->itemsPtr
в stackbuf
с каждым вызовом. len
- это длина stackbuf
, максимальное количество элементов, которые вы сможете сохранить в нем.
Дальнейшее чтение:
Ответ 2
Просто оживляя этот поток, найдя отличное объяснение. Ссылка Apple кажется сломанной. Вы можете попробовать здесь: https://developer.apple.com/library/ios/#samplecode/FastEnumerationSample/Introduction/Intro.html
Лучший пример реализации быстрого перечисления, который я нашел, - это: http://mikeash.com/pyblog/friday-qa-2010-04-16-implementing-fast-enumeration.html. Это выглядит намного хуже, чем есть.