2012-01-24 10 views
37

Sto tentando di aggiornare un MKMapView rimuovendo tutte le annotazioni al di fuori dell'area visibile e aggiungendo e rimuovendo alcune annotazioni all'interno dell'area visibile. Questo è il mio codice:NSSet to NSArray casting calling objectAtIndex?

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

Questo mi dà l'errore - [__ NSCFSet objectAtIndex:]: selettore non riconosciuto inviato ad esempio 0x13cd40 dopo la riga finale in cui ho lanciato newAnnotations a un NSArray quindi aggiungere le annotazioni. C'è qualcosa nel lanciare un array su un set che lo causa? Se è così, c'è un modo per aggirarlo?

risposta

160

Nonostante stai lanciando NSMutableSet-NSArray, così semplice fusione non farà NSSet classe rispondere ai messaggi NSArray s'. È necessario compilare un vero e proprio NSArray con gli elementi del NSSet come questo:

NSArray *array = [theNsSet allObjects]; 
+4

allObjects modifica l'ordine. Quindi objectAtIndex potrebbe non restituire l'inteso. – Vignesh

+10

@Vignesh Non sequitur. Un set non è ordinato. –

+0

La soluzione suggerita qui non funziona per me ...'[theNSSet allObjects]' aggiunge semplicemente NSSet come oggetto all'interno di un NSArray, che è un fallimento, perché non ho bisogno di un NSSet INSIDE di un NSArray, ho bisogno di un NSArray DAL contenuto del NSSet –

5

Lanciare un oggetto NSArray a NSArray non farà altro che indurre il compilatore a pensare che l'oggetto sia un NSArray. In realtà, l'oggetto è un oggetto NSSet e se si tenta di utilizzarlo come NSArray si verificherà un errore.

Un altro modo per vederlo è che il casting è solo un trucco sui puntatori, non sugli oggetti puntati, che rimangono inalterati.

Il cast è sicuro solo in alcuni casi, come quando si esegue il cast da una classe derivata a una classe base; o quando sei assolutamente sicuro che il tipo reale dell'oggetto sottostante sia coerente con il tipo a cui lo stai proiettando.

In ogni caso, nel vostro caso specifico, si potrebbe tentare di accedere agli elementi nsset attraverso un NSArray utilizzando:

[newAnnotations allObjects] 

This

restituisce un array contenente i membri del set, o un vuoto array se il set non ha membri.

3

Sì, si deve prima memorizzare il set in un array come questo ...

NSMutableArray *array = [NSMutableArray arrayWithArray:[set allObjects]]; 
1

passo successivo per essere seguire per convertire un NSSet in NSArray o 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); 
5

un altro modo per ottenere un NSMutableArray da un NSSet è

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

Inoltre, la soluzione proposta da satzkmr fornisce un avviso "Puntatore incompatibile". (Mi dispiace scrivere qui, non ho abbastanza reputazione per commentare).

Problemi correlati