Как работает быстрое перечисление (цикл) в Objective-C? (т.е.: для (NSString * aString в aDictionary) ...) - PullRequest
6 голосов
/ 22 августа 2009

Я работаю над реализацией настраиваемой панели поиска для довольно сложной таблицы и наткнулся на этот шаблон кода СНОВА. Это образец из книги «Начало разработки iPhone»:

- (void)handleSearchForTerm:(NSString *)searchTerm
 {
NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init];
[self resetSearch];

for (NSString *key in self.keys)
  {
    NSMutableArray *array = [self.names valueForKey:key];
    NSMutableArray *toRemove = [[NSMutableArray alloc] init];
    for (NSString *name in array)
    {
        if ([name rangeOfString:searchTerm
                      options:NSCaseInsensitiveSearch].location == NSNotFound)
            [toRemove addObject:name];
    }

    if ([array count] == [toRemove count])
        [sectionsToRemove addObject:key];
    [array removeObjectsInArray:toRemove];
    [toRemove release];
  }
[self.keys removeObjectsInArray:sectionsToRemove];
[sectionsToRemove release];
[table reloadData];
}

Часть, которая мне интересна, это раздел "for (имя NSString * в массиве)". Что это делает именно? Кажется, создается строка для каждого элемента в массиве. Кроме того, как это работает со словарями?

Спасибо!

Ответы [ 3 ]

15 голосов
/ 22 августа 2009

Эта конструкция представляет собой цикл for другого типа, который выполняется над элементами в коллекции Objective-C, а не в массиве C. Первая часть определяет объект, который устанавливается в один элемент коллекции при каждом запуске цикла, а вторая часть - это коллекция для перечисления. Например, код:

NSArray *array = [NSArray arrayWithObjects:@"foo", @"bar", nil];
for(NSString *string in array) {
    NSLog(string);
}

будет печатать:

foo
bar

Это определяет NSString *string, что при каждом запуске цикла устанавливается следующий объект в NSArray *array.

Аналогично, вы можете использовать перечисление с экземплярами NSSet (где порядок объектов не определен) и NSDictionary (где он будет перечислять по ключам, хранящимся в словаре - вы можете перечислять по значениям, перечисляя по ключам, затем вызов valueForKey: в словаре с использованием этого ключа).

Это очень похоже на конструкцию в C:

int array[2] = { 0, 1 };
for(int i = 0; i < 2; i++) {
    printf("%d\n", array[i]);
}

который печатает:

0
1

Это всего лишь синтаксический способ сделать код более читабельным и скрыть некоторые причудливые перечисления, которые входят в перечисление объектов в NSArray, NSSet или NSDictionary. Более подробная информация приведена в разделе Fast Enumeration документа Objective-C 2.0 Language Language.

3 голосов
/ 22 августа 2009

Это называется быстрое перечисление . Он проходит по массиву, устанавливая key для каждого элемента. Функционально то же самое, что и это:

NSString *key;
for ( NSInteger i = 0; i < [[ self keys ] count ]; i++ ) {
    key = [[ self keys ] objectAtIndex:i ];

    NSMutableArray *array = [self.names valueForKey:key];
    NSMutableArray *toRemove = [[NSMutableArray alloc] init];
    for (NSString *name in array)
    {
            if ([name rangeOfString:searchTerm
                  options:NSCaseInsensitiveSearch].location == NSNotFound)
                    [toRemove addObject:name];
    }

    if ([array count] == [toRemove count])
            [sectionsToRemove addObject:key];
    [array removeObjectsInArray:toRemove];
    [toRemove release];
}
2 голосов
/ 22 августа 2009

Это цикл for с одной итерацией для каждого ключа в словаре.

Конструкция for..in называется быстрым перечислением. Подробнее об этом можно прочитать в Руководство по программированию Objective-C 2.0 .

Как он работает с объектом, зависит от его реализации протокола NSFastEnumeration. Ссылка на класс NSDictionary описывает, как он работает со словарями:

В Mac OS X v10.5 и более поздних версиях NSDictionary поддерживает протокол NSFastEnumeration. Вы можете использовать конструкцию for… in для перечисления ключей словаря, как показано в следующем примере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...