更新

看起来这个问题已经在 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];

在您的情况下,我实现剪辑的方式(仅显示当前显示区域的注释)是:
  • 将委托(delegate)添加到您的 mapView 并实现 - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 方法以在区域更改时获得通知
  • 遍历所有对象以获取与该区域匹配的对象
  • 仅将这些对象的注释添加到您的 map 中(您可以在先前显示的注释和新注释之间实现一种合并,或者简单地从头开始,删除所有注释,并设置新注释

  • 当然,当用户缩小很多并且区域的范围太大(无法显示太多引脚)时,您必须做出决定:我是否显示所有注释 View (并承担风险) map 上的显示没有提供太多信息)或者我是否向用户设置了一条消息,说“放大以获取图钉”或其他什么。但这是另一个故事......;)

    关于iphone - MKMapView 一次加载所有注释 View (包括那些在当前矩形之外的 View ),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1262742/

    10-14 16:49
    查看更多