Почему быстрое перечисление не пропускает номера NSNumbers при указании строк NSStrings? - PullRequest
4 голосов
/ 03 августа 2011

Я думал, что знаю, как использовать быстрое перечисление, но есть кое-что, чего я не понимаю в этом.Если я создаю три NSString объекта и три NSNumber объекта и помещаю их в 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];

, тогда я делаю быстрое перечисление для всех NSString объектов, например:*

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

В консоли я получаю такой результат:

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

Я зарегистрировал только NSString s, но я получаю строку для каждого объекта в массиве, даже NSNumber и я не понимаю почему.Всегда ли быстрое перечисление использует каждый объект, содержащийся в массиве?

Ответы [ 8 ]

10 голосов
/ 03 августа 2011

Когда вы пишете цикл forin, подобный этому, каждый объект в массиве приводится как NSString, а затем распечатывает их в соответствии с запросом.

Если вам нужны только строки NSS, вам нужно написать что-то вродеэто:

for (id obj in array) {
    if ([obj isKindOfClass:[NSString class]]) {
        NSLog(@"str: %@", obj);
    }
}
8 голосов
/ 03 августа 2011

Цикл for all не знает различий между NSStrings и Integer - он просто пройдет весь массив, применит каждый из них как NSString и распечатает их, как вы и просили.

7 голосов
/ 03 августа 2011

Я почти уверен, что быстрое перечисление возвращает все объекты в массиве - все, что вы делаете в for (NSString *str in array), это приведение типов str к NSString. В теле цикла необходимо проверить класс возвращаемого объекта, чтобы убедиться, что это NSString.

for(NSString *str in array)
{
    if([str isKindOfClass:[NSString class]])
        NSLog(@"str : %@", str);
}
1 голос
/ 03 августа 2011

Каждый объект, который наследуется от NSObject, реализует описание метода - (NSString),% @ в строке формата Objective-C принимает соответствующий аргумент для% @ и вызывает метод его описания. Большинство подклассов NSObject реализуют свою собственную версиюиз - (NSString) описание.То же самое происходит, когда вы набираете

> po anObject

в отладчике.

1 голос
/ 03 августа 2011

Objective-C динамически типизирован, что означает, что во время выполнения (когда цикл фактически выполняется) все объекты фактически одного типа (id) с разными классами. Язык допускает необязательную статическую типизацию во время компиляции, но все, что делает, это проверяет, являются ли отправляемые вами сообщения действительными для помеченного вами типа. Это на самом деле не меняет поведение вашей программы. Если вы приведете объект к другому типу, чем он есть на самом деле, все, что вы делаете, это лжете компилятору и побеждаете его проверку типов.

1 голос
/ 03 августа 2011
for (NSString *str in array) {

- это способ перечисления всех элементов массива.

Вы ожидаете, что, указав NSString, вы получите только объекты этого типа не правильно. Скорее, все указатели объектов приводятся к этому типу (NSString*).

Посмотрите Быстрое перечисление в руководстве по языку программирования Objective-C.

0 голосов
/ 05 февраля 2013

в быстром перечислении без типизации, просто присваивая указатель на новый объект

0 голосов
/ 03 августа 2011

Я не понимаю, где неожиданное поведение, использование расширенного цикла for в NSMutableArray будет просто выполнять итерацию по каждому объекту в массиве, который в вашем случае равен 6, результат верный и ожидаемый.

Числа будут преобразованы в строки.

...