iOS: изменение NSFastEnumerationState, чтобы скрыть мутацию при перечислении
У меня есть случай, когда в моих коллекциях будут видоизменяться при перечислении. Но это не разрешено в iOS. При дальнейшем исследовании выяснилось, что NSFastEnumerationState является структурой типа ac следующим образом.
typedef struct {
unsigned long state;
id *itemsPtr;
unsigned long *mutationsPtr;
unsigned long extra[5];
} NSFastEnumerationState;
Поэтому state->mutationPtr обозначает, был ли изменен набор или нет, в зависимости от того, какие исключения были выброшены. Мы можем переопределить это, чтобы показать, что коллекция не является мутантной (даже если она видоизменена), так что исключения не генерируются. При переопределении мы можем достичь мутации при перечислении. Я не знаю, правильная ли это идея. Пожалуйста, дайте мне знать ваши предложения.
2 ответа
Идея неверна, просто скопируйте объект, который вы перечисляете, и перечислите копию.
Изменить: Чтобы ответить на ваши комментарии, кажется, что технически возможно достичь того, что вы хотите. Первым делом я обратился к документации по NSEnumerator, чтобы проверить, можете ли вы создать собственный перечислитель и реализовать собственный метод nextObject для решения проблемы. Вот что я нашел:
Примечание. Модифицировать изменяемую коллекцию при ее перечислении небезопасно. Некоторые перечислители могут в настоящее время разрешать перечисление измененной коллекции, но это поведение не гарантируется в будущем.
Кроме того, я проверил Enumeration: обход элементов коллекции - используя раздел Enumerator и обнаружил очень похожую вещь:
Не безопасно удалять, заменять или добавлять элементы изменяемой коллекции при перечислении через нее. Если вам нужно изменить коллекцию во время перечисления, вы можете либо сделать копию коллекции и перечислить ее, используя копию, либо собрать информацию, которая вам требуется во время перечисления, и применить изменения позже.
Итак, если вы подытожите все это, мне кажется, что у вас есть 2 варианта:
- Создайте свой собственный подкласс NSEnumerator и используйте его, чтобы делать то, что вам нужно.
- Никогда не используйте NSFastEnumeration и найдите другой способ сделать то, что вам нужно.
http://www.mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html Эта ссылка дала некоторую полезную информацию по этому вопросу. Это мне очень помогло.