Подтвердить что ты не робот

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, затем добавьте аннотации. Есть ли что-то о том, чтобы привести массив к множеству, который вызывает это? Если да, есть ли способ обойти его?

4b9b3361

Ответ 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);