更新
看起来这个问题已经在 iOS 4.3 中悄悄修复了。到目前为止,被认为“足够远”以供注释循环使用的距离似乎有数百英里,即使放大得很近也是如此。当我使用 iOS 4.3 SDK 构建我的应用程序时,会根据更合理的限制回收注释。
有没有其他人遇到过这个问题?这是代码:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(WWMapAnnotation *)annotation {
// Only return an Annotation view for the placemarks. Ignore for the current location--the iPhone SDK will place a blue ball there.
NSLog(@"Request for annotation view");
if ([annotation isKindOfClass:[WWMapAnnotation class]]){
MKPinAnnotationView *browse_map_annot_view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"BrowseMapAnnot"];
if (!browse_map_annot_view) {
browse_map_annot_view = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"BrowseMapAnnot"] autorelease];
NSLog(@"Creating new annotation view");
} else {
NSLog(@"Recycling annotation view");
browse_map_annot_view.annotation = annotation;
}
...
一旦显示 View ,我就会得到
2009-08-05 13:12:03.332 xxx[24308:20b] Request for annotation view
2009-08-05 13:12:03.333 xxx[24308:20b] Creating new annotation view
2009-08-05 13:12:03.333 xxx[24308:20b] Request for annotation view
2009-08-05 13:12:03.333 xxx[24308:20b] Creating new annotation view
等等,对于我添加的每个注释(~60)。 map (正确)仅显示当前矩形中的两个注释。我在 viewDidLoad 中设置区域:
if (center_point.latitude == 0) {
center_point.latitude = 35.785098;
center_point.longitude = -78.669899;
}
if (map_span.latitudeDelta == 0) {
map_span.latitudeDelta = .001;
map_span.longitudeDelta = .001;
}
map_region.center = center_point;
map_region.span = map_span;
NSLog(@"Setting initial map center and region");
[browse_map_view setRegion:map_region animated:NO];
在请求任何注释 View 之前,正在设置的区域的日志条目会打印到控制台。
这里的问题是,由于所有的注释都是一次请求的,[mapView dequeueReusableAnnotationViewWithIdentifier] 什么也不做,因为 map 上的每个注释都有唯一的 MKAnnotationViews。这导致了我的内存问题。
一个可能的问题是这些注释聚集在一个非常小的空间(约 1 英里半径)中。尽管 map 在 viewDidLoad(纬度和经度 delta .001)中被放大得很紧,但它仍然一次加载所有注释 View 。
谢谢...
最佳答案
您所期望的是基于 map 显示的当前 region
的注释 View 的某种“剪裁”。
这不是 dequeueReusableAnnotationViewWithIdentifier
选择器的工作方式。
从它的文档:
随着注释 View 移出屏幕, map View 将它们移至内部管理的重用队列。随着新注释在屏幕上移动,并且提示您的代码提供相应的注释 View ,您应该始终尝试在创建新 View 之前将现有 View 出列。
因此,可重用机制仅在您调用如下序列时才有意义:
//this will create 1000 annotation views
[theMap addAnnotations:my1000annotations];
//this will move them offscreen (but some annotation views may be kept internally for further reuse)
[theMap removeAnnotatios:theMap.annotations];
//when adding back again some annotations onscreen, some of the previous annotation views will be reused.
[theMap addAnnotations:someNew400annotations];
在您的情况下,我实现剪辑的方式(仅显示当前显示区域的注释)是:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
方法以在区域更改时获得通知 当然,当用户缩小很多并且区域的范围太大(无法显示太多引脚)时,您必须做出决定:我是否显示所有注释 View (并承担风险) map 上的显示没有提供太多信息)或者我是否向用户设置了一条消息,说“放大以获取图钉”或其他什么。但这是另一个故事......;)
关于iphone - MKMapView 一次加载所有注释 View (包括那些在当前矩形之外的 View ),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1262742/