Objective-C: введение в коллекции и enumerator
Быстрое перечисление (перебор) с помощью enumerator
— это функция Objective-C, которая помогает перечислить коллекцию. Поэтому, чтобы узнать о перечислении все, нам нужно сначала узнать базовые вещи о коллекции, о которой вскользь поговорим в этой большой статье об enumerator’ах в Objective-C.
Коллекции в Objective-C
Коллекции (collections) — это фундаментальная конструкция. Они используются для хранения и управления другими объектами. Смысл коллекции заключается в том, что она предоставляет общий способ эффективного хранения и извлечения объектов.
Существует несколько различных типов коллекций. Хотя все они выполняют одну и ту же задачу — хранить другие объекты, все они отличаются друг от друга в основном способом извлечения объектов.
Наиболее распространенные коллекции, используемые в Objective-C, — это:
- NSSet.
- NSArray.
- NSDictionary.
- NSMutableSet.
- NSMutableArray.
- NSMutableDictionary.
Если вы хотите узнать больше об этих структурах, пожалуйста, ознакомьтесь с хранением данных в Foundation Framework (fast enumeration).
О коллекциях с точки зрения производительности
Выбор подходящей коллекции для вашего случая использования важен не только для простоты реализации, но и для производительности.
В реальной жизни можно увидеть, насколько ужасными и тормозными могут быть некоторые алгоритмы при резком увеличении числа элементов для перебора.
Поэтому ниже подробней опишем некоторые из популярных коллекций с точки зрения их производительности:
- NSArray — лучший выбор для списка элементов, если вы собираетесь выполнять последовательный итерационный просмотр или обращаться непосредственно к ним по индексу. Их также можно эффективно использовать в качестве очереди или стека, так как добавление или удаление элементов из начала (или в начале) выполняется за O(1). Проверка наличия объекта в массиве с помощью
containsObject
является операцией уровня O(N), поскольку для поиска совпадения может потребоватьсяN
сравнений. - NSSet — отличный выбор для проверки
containsObject
благодаря эффективным алгоритмам хэширования. Добавление/удаление элементов всегда O(1). Кроме того, у вас есть быстрые арифметические операции с наборами. - NSDictionary — отличный выбор, если у вас есть естественный ключ, который вы можете использовать для доступа к объектам. Он не имеет присущего ему порядка, но если вы знаете ключ, то можете получить любой объект за O(1).
Синтаксис быстрого перечисления
Перечислитель (enumerator) — это список предопределенных переменных. Если вы знакомы с типами данных Objective C, такими как int
и double
, вы знаете, что можно определить переменные для хранения или последовательного возврата значений int
и double
.
Перечислители (fast enumeration) также являются типом данных — разница лишь в том, что вы создаете этот тип данных сами. С помощью перечислителей вы можете создавать переменные, которые будут хранить только значение, найденное только в перечислителе. Перечислители объявляются с помощью ключевого слова enum
.
Кроме улучшения производительности, тип данных enumerator очень полезен при написании больших программ. Он улучшает читабельность и помогает избежать ошибок.
Синтаксис для создания перечислимого типа данных следующий:
for (classType variable in collectionObject ) { statements }
А вот пример быстрого перечисления на базе определения выше:
#import <Foundation/Foundation.h> int main() { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSArray *array = [[NSArray alloc] initWithObjects:@"string1", @"string2",@"string3",nil]; for(NSString *aString in array) { NSLog(@"Value: %@",aString); } [pool drain]; return 0; }
Теперь, когда мы скомпилируем и запустим программу, мы получим следующий вывод:
2013-09-28 06:26:22.835 demo[7426] Value: string1
2013-09-28 06:26:22.836 demo[7426] Value: string2
2013-09-28 06:26:22.836 demo[7426] Value: string3
Как видно из вывода, каждый из объектов в массиве выводится по порядку.
Быстрое перечисление в обратном порядке
Для более сложного упражнения давайте заюзаем такой цикл:
for (classType variable in [collectionObject reverseObjectEnumerator] ) { statements }
Вот пример использования reverseObjectEnumerator
в быстром перечислении.
#import <Foundation/Foundation.h> int main() { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSArray *array = [[NSArray alloc] initWithObjects:@"string1", @"string2",@"string3",nil]; for(NSString *aString in [array reverseObjectEnumerator]) { NSLog(@"Value: %@",aString); } [pool drain]; return 0; }
Теперь, когда мы скомпилируем и запустим программу, мы получим следующий результат:
2013-09-28 06:27:51.025 demo[12742] Value: string3
2013-09-28 06:27:51.025 demo[12742] Value: string2
2013-09-28 06:27:51.025 demo[12742] Value: string1
Как видно из вывода, каждый из объектов в массиве выводится, но в обратном порядке по сравнению с обычным быстрым перечислением.
Подведение итогов
Используйте массивы, словари, множества и специализированные коллекции для хранения и итерации групп объектов или значений.
Классы коллекций Foundation являются базовыми строительными блоками каждого приложения Mac/iOS. В этой статье мы подробно рассмотрели как «старые» (NSArray, NSSet
), так и «новые» (NSMapTable, NSHashTable, NSPointerArray
) классы, привели примеры работы некоторых из них и кратко обсудили, когда что использовать.
Имейте в виду, что популярные NSArrays
неизменяемы (имутабельны), поэтому вы не можете добавлять в них новые объекты. Для добавления или удаления объектов в массив мы используем изменяемые массивы.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: