Как перечислить произвольный набор, который соответствует NSFastEnumeration

Я пытаюсь перечислить несколько объектов, которые, в зависимости от ситуации, могут быть либо NSArray, либо NSOrderedSet. Так как оба соответствуют NSFastEnumeration, я ожидаю, что это сработает:

id<NSFastEnumeration> enumerableSet =
(test) ?
[NSArray arrayWithObjects:@"one", @"two", @"three", nil] :
[NSOrderedSet orderedSetWithObjects:@"one", @"two", @"three", nil];

NSEnumerator *e = [enumerableSet objectEnumerator];

Однако я получаю следующую ошибку компилятора:

Нет известного метода экземпляра для селектора 'objectEnumerator'.

Я подозреваю, что здесь есть какая-то синтаксическая ошибка, я до этого мало работал с конструкцией id. Я мог бы преобразовать один или оба набора в общий класс, но, если возможно, я бы хотел лучше понять, что здесь происходит.

3 ответа

Решение

objectEnumerator не заявлено в NSFastEnumeration протокол, поэтому с помощью [enumerableSet objectEnumerator]; не будет работать, потому что вы работаете с типом `id', который не определяет этот метод.

поскольку objectEnumerator объявлен как свойство NSArray и NSSet (без общего суперкласса), вам нужно будет установить перечислитель из переменной, которая знает, что это массив / набор. То есть:

NSEnumerator *e = 
(test) ?
[[NSArray arrayWithObjects:@"one", @"two", @"three", nil] objectEnumerator]:
[[NSOrderedSet orderedSetWithObjects:@"one", @"two", @"three", nil] objectEnumerator];

Хорошо, неважно Я только что нашел свой ответ. objectEnumerator не является частью протокола - поэтому, хотя NSArray и NSOrderedSet имеют сообщение objectEnumerator, я не могу использовать его таким образом. Вместо этого это, кажется, работает:

NSEnumerator *e =
(test) ?
[[NSArray arrayWithObjects:@"one", @"two", @"three", nil] objectEnumerator]:
[[NSOrderedSet orderedSetWithObjects:@"one", @"two", @"three", nil] objectEnumerator];

У вас есть объекты, которые соответствуют NSFastEnumeration протокол, но вы пытаетесь использовать "медленное" перечисление с NSEnumerator, Вместо этого используйте быстрое перечисление:

id<NSFastEnumeration> enumerableSet =
(test) ?
[NSArray arrayWithObjects:@"one", @"two", @"three", nil] :
[NSOrderedSet orderedSetWithObjects:@"one", @"two", @"three", nil];

for (id object in enumerableSet) {
    // ...
}

См. Быстрое перечисление. Упрощает перечисление коллекции в программировании Apple с Objective-C.

Я рекомендую использовать быстрое перечисление вместо NSEnumerator где это возможно; быстрое перечисление яснее, кратче и быстрее.

Другие вопросы по тегам