NSSet для NSArray, вызывающего вызов objectAtIndex?
Я пытаюсь обновить MKMapView, удалив все аннотации вне видимой области и добавив и удалив некоторые аннотации внутри видимой области. Это мой код:
NSSet *visibleAnnotations = [mapView annotationsInMapRect:[mapView visibleMapRect]];
NSSet *allAnnotations = [NSSet setWithArray:[mapView annotations]];
NSMutableSet *nonVisibleAnnotations = [NSMutableSet setWithSet:allAnnotations];
[nonVisibleAnnotations minusSet:visibleAnnotations];
[mapView removeAnnotations:(NSArray *)nonVisibleAnnotations];
NSMutableSet *newAnnotations = [NSMutableSet setWithArray:[_zoomLevels objectAtIndex:clusterLevel]];
[newAnnotations minusSet:visibleAnnotations];
[mapView addAnnotations:(NSArray *)newAnnotations];
Это дает мне ошибку - [__ NSCFSet objectAtIndex:]: нераспознанный селектор, посланный экземпляру 0x13cd40 после последней строки, в которую я передал newAnnotations в NSArray, затем добавьте аннотации. Есть ли что-то о том, чтобы привести массив к множеству, который вызывает это? Если да, есть ли способ обойти его?
Ответы
Ответ 1
Несмотря на то, что вы выбрали NSMutableSet
to NSArray
, это простое кастинг не приведет к тому, что класс NSSet
будет отвечать на сообщения NSArray
. Вы должны заполнить фактический NSArray
элементами NSSet
следующим образом:
NSArray *array = [theNsSet allObjects];
Ответ 2
Приведение объекта NSSet
к NSArray
не приведет к тому, что обманывает компилятор, думая, что объект является NSArray
. Фактически, объект является объектом NSSet
и пытается использовать его как NSArray
, который приведет к сбою.
Другим способом увидеть это является то, что кастинг - это просто трюк на указателях, а не на объектах с указателем, которые остаются неизменными.
Кастинг безопасен только в некоторых случаях, например, когда вы отбрасываете производный класс в базовый класс; или когда вы абсолютно уверены, что реальный тип базового объекта соответствует типу, на который вы его производите.
В любом случае, в вашем конкретном случае вы можете попытаться получить доступ к элементам NSSet через NSArray, используя:
[newAnnotations allObjects]
Это
Возвращает массив, содержащий элементы набора, или пустой массив, если в наборе нет элементов.
Ответ 3
Другой способ получить NSMutableArray из NSSet -
NSMutableArray * array= [[set allObjects] mutableCopy];
Кроме того, решение, предложенное satzkmr, дает вам предупреждение "Несовместимый указатель". (Извините, что написал это здесь, у меня недостаточно репутации для комментариев).
Ответ 4
Да, вы должны сначала сохранить набор в массив, подобный этому...
NSMutableArray *array = [NSMutableArray arrayWithArray:[set allObjects]];
Ответ 5
Следующий шаг, который необходимо выполнить для преобразования NSSet в NSArray или NSMutableArray,
NSSet *airports = [NSSet setWithObjects:@"Chennai",@"Mumbai",@"Delhi", nil];
NSLog(@"Set Elemets Before Move:%@", airports);
NSMutableArray *movedAirports = [airports allObjects];
NSLog(@"Array Elements After Moving from Set:%@", movedAirports);