Перечисление: пересечение элементов набора
Какао определяет три основных способа перечислить содержание набора. Они включают быстрое перечисление и основанное на блоке перечисление. Существует также NSEnumerator
класс, хотя это обычно заменялось быстрым перечислением.
Быстрое перечисление
Быстрое перечисление является предпочтительным методом перечисления содержания набора, потому что это предоставляет следующие преимущества:
Перечисление более эффективно, чем использование
NSEnumerator
непосредственно.Синтаксис краток.
Перечислитель повышает исключение при изменении набора при перечислении.
Можно выполнить многократные перечисления одновременно.
Поведение для быстрого перечисления варьируется немного основанное на типе набора. Массивы и наборы перечисляют свое содержание, и словари перечисляют свои ключи. NSIndexSet
и NSIndexPath
не поддерживайте быстрое перечисление. Можно использовать быстрое перечисление с объектами коллекции, как показано в Перечислении 1.
Перечисление 1 Используя быстрое перечисление со словарем
for (NSString *element in someArray) { |
NSLog(@"element: %@", element); |
} |
NSString *key; |
for (key in someDictionary){ |
NSLog(@"Key: %@, Value %@", key, [someDictionary objectForKey: key]); |
} |
Для получения дополнительной информации о быстром перечислении посмотрите Быстрое Перечисление в Языке программирования Objective C.
Используя основанное на блоке перечисление
NSArray
, NSDictionary
, и NSSet
позвольте перечисление их блоков использования содержания. Для перечисления с блоком вызовите надлежащий метод и укажите блок для использования. Перечисление 2 демонстрирует основанное на блоке перечисление для NSArray
объект.
Перечисление 2 Основанное на блоке перечисление массива
NSArray *anArray = [NSArray arrayWithObjects:@"A", @"B", @"D", @"M", nil]; |
NSString *string = @"c"; |
[anArray enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop){ |
if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) { |
NSLog(@"Object Found: %@ at index: %i",obj, index); |
*stop = YES; |
} |
} ]; |
Для NSSet
объект, можно использовать подобный код, как показано в Перечислении 3.
Перечисление 3 Основанное на блоке перечисление набора
NSSet *aSet = [NSSet setWithObjects: @"X", @"Y", @"Z", @"Pi", nil]; |
NSString *aString = @"z"; |
[aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop){ |
if ([obj localizedCaseInsensitiveCompare:aString]==NSOrderedSame) { |
NSLog(@"Object Found: %@", obj); |
*stop = YES; |
} |
} ]; |
Для NSArray
перечисление, индексный параметр полезен для параллельного перечисления. Без этого параметра единственный способ получить доступ к индексу состоял бы в том, чтобы использовать indexOfObject:
метод, который неэффективен. Параметр остановки важен для производительности, потому что это позволяет перечислению останавливаться рано на основе некоторого условия, определенного в блоке. Основанные на блоке методы перечисления для других наборов немного отличаются на имя и на блочную подпись. Посмотрите соответствующие ссылки класса для определений метода.
Используя перечислитель
NSEnumerator
простой абстрактный класс, подклассы которого перечисляют наборы других объектов. Объекты коллекции — такие как массивы, наборы и словари — обеспечивают особенный NSEnumerator
объекты, с которыми можно перечислить их содержание. Вы отправляете nextObject
неоднократно к недавно создаваемому NSEnumerator
объект иметь его возвращает следующий объект в исходном наборе. Когда набор исчерпывается, он возвращается nil
. Вы не можете «сбросить» перечислитель после того, как он исчерпал свой набор. Для перечисления набора снова необходимо создать новый перечислитель.
Классы набора такой как NSArray
, NSSet
, и NSDictionary
включайте методы, возвращающие перечислитель, надлежащий типу набора. Например, NSArray
имеет два метода, возвращающиеся NSEnumerator
объект: objectEnumerator
и reverseObjectEnumerator
. NSDictionary
класс также имеет два метода, возвращающиеся NSEnumerator
объект: keyEnumerator
и objectEnumerator
. Эти методы позволяют Вам перечислить содержание NSDictionary
объект ключом или значением, соответственно.
В Objective C, NSEnumerator
объект сохраняет набор, по которому он перечисляет (если он не реализован по-другому пользовательским подклассом).
Не безопасно удалить, заменить, или добавить к элементам непостоянного набора при перечислении через него. Если необходимо изменить набор во время перечисления, можно или сделать копию набора и перечислить использование копии или собрать информацию, которой Вы требуете во время перечисления и применяете изменения впоследствии. Второй образец проиллюстрирован в Перечислении 4.
Перечисление 4 , Перечисляющее словарь и удаляющее объекты
NSMutableDictionary *myMutableDictionary = <#Get a mutable dictionary#> ; |
NSMutableArray *keysToDeleteArray = |
[NSMutableArray arrayWithCapacity:[myMutableDictionary count]]; |
NSString *aKey; |
NSEnumerator *keyEnumerator = [myMutableDictionary keyEnumerator]; |
while (aKey = [keyEnumerator nextObject]) |
{ |
if ( /* test criteria for key or value */ ) { |
[keysToDeleteArray addObject:aKey]; |
} |
} |
[myMutableDictionary removeObjectsForKeys:keysToDeleteArray]; |