web-dev-qa-db-ja.com

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に送信された認識されないセレクター NSArrayにnewAnnotationsをキャストし、注釈を追加した最後の行の後。これを引き起こすセットに配列をキャストすることについて何かありますか?もしそうなら、それを回避する方法はありますか?

43
benwad

NSMutableSetNSArrayにキャストしているにもかかわらず、その単純なキャストではNSSetクラスがNSArrayのメッセージに応答しません。次のように、実際のNSArrayNSSetの要素を入力する必要があります。

NSArray *array = [theNsSet allObjects];
174
user529758

NSSetオブジェクトをNSArrayにキャストしても、オブジェクトがNSArrayであるとコンパイラーに思い込ませることはありません。実際、オブジェクトNSSetオブジェクトであり、NSArrayとして使用しようとすると失敗します。

別の見方をすれば、キャストは、変更されないままの、指示先のオブジェクトではなく、ポインターに対する単なるトリックであるということです。

キャストは、派生クラスから基本クラスにキャストするときなど、特定の場合にのみ安全です。または、基になるオブジェクトの実際の型が、キャスト先の型と一致していることが確実にわかっている場合。

とにかく、あなたの特定のケースでは、NSArrayを介してNSSet要素にアクセスしようとするかもしれません:

 [newAnnotations allObjects]

これ

セットのメンバーを含む配列、またはセットにメンバーがない場合は空の配列を返します。

6
sergio

NSSetからNSMutableArrayを取得する別の方法は、

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

また、satzkmrによって提案されたソリューションでは、「互換性のないポインター」警告が表示されます。 (これをここで書くことは残念ですが、私はコメントするのに十分な評判を持っていません)。

5
ACBM

はい、最初にこのような配列にセットを保存する必要があります...

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

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);
1
satzkmr