50

我正在尝试通过删除可见区域外的所有注释以及在可见区域内添加和删除一些注释来更新 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:]: unrecognized selector sent to instance 0x13cd40在我将 newAnnotations 转换为 NSArray 然后添加注释的最后一行之后。有没有关于将数组转换为导致这种情况的集合?如果是这样,有没有办法绕过它?

4

6 回答 6

186

尽管您正在转换NSMutableSetNSArray,但这种简单的转换不会使NSSet班级响应NSArray的消息。您必须NSArray使用以下元素填充实际NSSet

NSArray *array = [theNsSet allObjects];
于 2012-01-24T10:16:34.577 回答
6

NSSet对象强制转换为NSArray不会做任何其他欺骗编译器认为该对象是NSArray. 实际上,对象对象,试图NSSet将其用作对象NSArray将产生失败。

另一种看待它的方式是,强制转换只是指针上的一个技巧,而不是指向对象的技巧,它保持不变。

强制转换仅在某些情况下是安全的,例如从派生类转换为基类时;或者当您绝对确定底层对象的真实类型与您将其转换为的类型一致时。

无论如何,在您的特定情况下,您可以尝试使用以下方法通过 NSArray 访问 NSSet 元素:

 [newAnnotations allObjects]

返回一个包含集合成员的数组,如果集合没有成员,则返回一个空数组。

于 2012-01-24T10:15:55.253 回答
5

从 NSSet 获取 NSMutableArray 的另一种方法是

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

此外, satzkmr 提出的解决方案会为您提供“不兼容的指针”警告。(很抱歉在这里写这个,我没有足够的声誉来评论)。

于 2014-06-10T19:05:05.553 回答
3

是的,您应该首先将集合存储到这样的数组中......

NSMutableArray *array = [NSMutableArray arrayWithArray:[set allObjects]];
于 2012-07-03T06:45:18.320 回答
1

按照步骤将 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);
于 2013-11-13T10:00:02.930 回答
-1
NSArray *array = [sets allObjets];
于 2019-11-27T13:03:09.230 回答