web-dev-qa-db-fra.com

NSSet vers NSArray cast appelant objectAtIndex?

J'essaie de mettre à jour un MKMapView en supprimant toutes les annotations en dehors de la zone visible, et en ajoutant et en supprimant certaines annotations à l'intérieur de la zone visible. Voici mon code:

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];

Cela me donne l'erreur - [__ NSCFSet objectAtIndex:]: sélecteur non reconnu envoyé à l'instance 0x13cd4 après la dernière ligne dans laquelle je cast newAnnotations à un NSArray puis ajoute les annotations. Y a-t-il quelque chose à propos de la conversion d'un tableau dans un ensemble qui provoque cela? Si oui, y a-t-il une solution?

43
benwad

Bien que vous convertissiez NSMutableSet en NSArray, cette simple conversion ne fera pas que la classe NSSet répondra aux messages de NSArray. Vous devez remplir un NSArray réel avec les éléments du NSSet comme ceci:

NSArray *array = [theNsSet allObjects];
174
user529758

La conversion d'un objet NSSet en NSArray ne fera rien d'autre que d'inciter le compilateur à penser que l'objet est un NSArray. En fait, l'objet est un objet NSSet et essayer de l'utiliser comme NSArray entraînera un échec.

Une autre façon de le voir est que le lancer n'est qu'une astuce sur les pointeurs, pas sur les objets pointés, qui restent inchangés.

La conversion n'est sûre que dans certains cas, comme lorsque vous effectuez une conversion d'une classe dérivée vers une classe de base; ou lorsque vous êtes absolument sûr que le type réel de l'objet sous-jacent est cohérent avec le type vers lequel vous le transformez.

Quoi qu'il en soit, dans votre cas spécifique, vous pouvez essayer d'accéder aux éléments NSSet via un NSArray en utilisant:

 [newAnnotations allObjects]

Ce

Renvoie un tableau contenant les membres de l'ensemble ou un tableau vide si l'ensemble n'a pas de membres.

6
sergio

Une autre façon d'obtenir un NSMutableArray à partir d'un NSSet est

NSMutableArray * array= [[set allObjects] mutableCopy];

De plus, la solution proposée par satzkmr vous donne un avertissement "Pointeur incompatible". (Désolé d'écrire ceci ici, je n'ai pas assez de réputation pour commenter).

5
ACBM

Oui, vous devez d'abord stocker l'ensemble dans un tableau comme celui-ci ...

NSMutableArray *array = [NSMutableArray arrayWithArray:[set allObjects]];
3
Nishant

Étape suivante à suivre pour convertir un NSSet en NSArray ou 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);
1
satzkmr