NSSet转换为NSObject并调用objectAtIndex?

问题描述 投票:44回答:6

我正在尝试通过删除可见区域外的所有注释,并在可见区域内添加和删除一些注释来更新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然后添加注释的最后一行之后。关于将数组强制转换为集合会导致这种情况吗?如果是这样,有办法解决吗?

objective-c ios nsarray mkmapview nsset
6个回答
176
投票

尽管您将NSMutableSet强制转换为NSArray,但简单的强制转换不会使NSSet类响应NSArray的消息。您必须像这样用NSArray的元素填充实际的NSSet

NSArray *array = [theNsSet allObjects];

6
投票

NSSet对象投射到NSArray不会做任何其他使欺骗编译器认为该对象是NSArray的事情。实际上,对象isNSSet对象,尝试将其用作NSArray会产生故障。

另一种看待方式是强制转换只是对指针的一种欺骗,而不是对保持不变的指向对象的欺骗。

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

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

 [newAnnotations allObjects]

This

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


5
投票

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

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

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


3
投票

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

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

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

-1
投票
NSArray *array = [sets allObjets];
© www.soinside.com 2019 - 2024. All rights reserved.