Question

I am trying to enumerate over a bunch of objects which, depending on the situation, may be either an NSArray or an NSOrderedSet. Since both conform to NSFastEnumeration, I would expect this to work:

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

NSEnumerator *e = [enumerableSet objectEnumerator];

However, I get the following compiler error:

No known instance method for selector 'objectEnumerator'.

I suspect there is some syntax error here, I haven't worked much with the id construct before. I could convert one or both of the sets to a common class, but if possible I'd like to understand better what's going on here.

Was it helpful?

Solution

objectEnumerator is not declared in the NSFastEnumeration protocol, therefore using [enumerableSet objectEnumerator]; will not work because you are working with type `id' which doesn't define that method.

Since objectEnumerator is declared as a property of a NSArray and a NSSet (with no common super class), you will need to set the enumerator from a variable which knows that it is an array/set. I.e.:

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

OTHER TIPS

Ok, never mind. I just found my answer. objectEnumerator is not part of the protocol - so although both NSArray and NSOrderedSet have an objectEnumerator message, I can't use it this way. Instead, this seems to work:

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

You have objects that conform to the NSFastEnumeration protocol, but you are trying to use ‘slow’ enumeration with NSEnumerator. Instead, use fast enumeration:

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

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

See Fast Enumeration Makes It Easy to Enumerate a Collection in Apple’s Programming with Objective-C.

I recommend using fast enumeration instead of NSEnumerator wherever possible; fast enumeration is clearer, more concise and faster.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top