Why does fast enumeration not skip the NSNumbers when I specify NSStrings?

别等时光非礼了梦想. 提交于 2019-12-19 09:06:36

问题


I thought that I knew how to use fast enumeration, but there is something I don't understand about it. If I create three NSString objects and three NSNumber objects 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 make do fast enumeration on all NSString objects, like this:

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 logged only the NSStrings, but I get a line for every object in the array, even the NSNumbers and I don't understand why. Does fast enumeration always use every object contained in an array?


回答1:


When you write a forin loop like that, it casts every object in the array as an NSString, then prints them out as requested.

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

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



回答2:


The for all loop doesn't know the difference between NSStrings and Integers -- it will simply go through the entire array, cast each as an NSString, and print them out as you asked.




回答3:


I'm pretty sure that fast enumeration returns all objects in the array- all that you're doing in for (NSString *str in array) is typecasting str to an NSString. In the body of the loop you need to check the class of the returned object to make sure that it is an NSString.

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



回答4:


Objective-C is dynamically typed, meaning that at runtime (when the loop actually runs), objects are all effectively one type (id) with different classes. The language allows optional compile-time static typing, but all that does is check whether the messages you're sending are valid for the type you've marked. It doesn't actually change the behavior of your program. If you cast an object to be a different type than it actually is, all you're doing is lying to the compiler and defeating its type-checker.




回答5:


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

> po anObject

in the debugger.




回答6:


for (NSString *str in array) {

is a way to enumerate through all the elements in array.

You expectative that by specifying NSString you get only the objects of that type is not correct. Rather, all the objects pointers are cast to that type (NSString*).

Have a look at Fast Enumeration in The Objective-C Programming Language guide.




回答7:


I don't understand where is the unexpected behavior, using the enhanced for loop in an NSMutableArray will just iterate thru every single object in the array which in your case is 6, the result is correct and expected.

The numbers will just get casted to Strings.




回答8:


in fast enumeration no typecasting,just assigning the pointer into new object



来源:https://stackoverflow.com/questions/6918620/why-does-fast-enumeration-not-skip-the-nsnumbers-when-i-specify-nsstrings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!