Why doesn't fast enumeration skip NSNumbers when I specify NSStrings?

I thought I knew how to use quick enumeration, but I don’t understand something about this. If I create three NSString objects and three NSNumber and put them in an NSMutableArray :

 NSString *str1 = @"str1"; NSString *str2 = @"str2"; NSString *str3 = @"str3"; NSNumber *nb1 = [NSNumber numberWithInt:1]; NSNumber *nb2 = [NSNumber numberWithInt:2]; NSNumber *nb3 = [NSNumber numberWithInt:3]; NSArray *array = [[NSArray alloc] initWithObjects:str1, str2, str3, nb1, nb2, nb3, nil]; 

then I do a quick enumeration on all NSString objects, for example:

 for (NSString *str in array) { NSLog(@"str : %@", str); } 

In the console, I get this result:

 2011-08-02 13:53:12.873 FastEnumeration[14172:b603] str : str1 2011-08-02 13:53:12.874 FastEnumeration[14172:b603] str : str2 2011-08-02 13:53:12.875 FastEnumeration[14172:b603] str : str3 2011-08-02 13:53:12.875 FastEnumeration[14172:b603] str : 1 2011-08-02 13:53:12.876 FastEnumeration[14172:b603] str : 2 2011-08-02 13:53:12.876 FastEnumeration[14172:b603] str : 3 

I registered only NSString s, but I get a string for every object in the array, even NSNumber , and I don't understand why. Does fast enumeration always use every object contained in an array?

+4
source share
8 answers

When you write such a forin loop, it throws every object in the array as an NSString, and then prints them out as requested.

If you want only NSStrings, you need to write something like this:

 for (id obj in array) { if ([obj isKindOfClass:[NSString class]]) { NSLog(@"str: %@", obj); } } 
+10
source

The for all loop does not know the difference between NSStrings and Integer - it will just go through the entire array, discard each as an NSString and print them as you requested.

+8
source

I am sure that a quick enumeration returns all the objects in the array - all you do in for (NSString *str in array) is casting str types to NSString . The body of the loop you need to check the class of the returned object to see if it is NSString .

 for(NSString *str in array) { if([str isKindOfClass:[NSString class]]) NSLog(@"str : %@", str); } 
+7
source
 for (NSString *str in array) { 

- a way to list all the elements in an array.

You expect that by specifying NSString you will only get objects of this type that are incorrect. Most likely, all object pointers are passed to this type ( NSString* ).

See Quick Listing in the Objective-C Programming Language Guide.

+1
source

Objective-C is dynamically typed, which means that at runtime (when the loop actually runs), the objects are actually the same type ( id ) with different classes. The language allows for optional static typing at compile time, but all that happens is to check whether the messages you send are valid for the type you specify. This does not actually change the behavior of your program. If you put an object on a different type than it actually is, everything you do lies with the compiler and damages its type checking method.

+1
source

Each object that descends from NSObject implements a description of the method - (NSString),% @in Objective-C formate string will take the corresponding argument for% @ and call its description method. Most NSObject subclasses will implement their own version of - (NSString) there. The same thing happens when you type

 > po anObject 

in the debugger.

+1
source

I don’t understand where the unexpected behavior, using the extended loop cycle in NSMutableArray , will just NSMutableArray through each individual object in the array, which in your case is 6, the result will be correct and expected.

The numbers will simply be added to the lines.

0
source

there is no typecasting in quick enumeration, just assigning a pointer to a new object

0
source

All Articles