13

更新

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

...

显示视图后,我得到

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),等等。地图(正确)仅显示当前矩形中的两个注释。我在 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];

在请求任何注释视图之前,正在设置的区域的日志条目会打印到控制台。

这里的问题是,由于一次请求所有注释,[mapView dequeueReusableAnnotationViewWithIdentifier] 什么都不做,因为地图上的每个注释都有唯一的 MKAnnotationViews。这导致了我的记忆问题。

一个可能的问题是这些注释聚集在一个非常小的空间(约 1 英里半径)中。尽管地图在 viewDidLoad(纬度和经度增量 0.001)中被放大得非常紧密,但它仍然会一次加载所有注释视图。

谢谢...

4

2 回答 2

14

region您所期望的是基于当前地图显示的注释视图的某种“剪裁” 。

这不是dequeueReusableAnnotationViewWithIdentifier选择器的工作方式。

从其文档中: 随着注释视图移出屏幕,地图视图将它们移动到内部管理的重用队列。随着新注释在屏幕上移动,并且您的代码被提示提供相应的注释视图,您应该始终尝试在创建新视图之前使现有视图出列。

因此,仅当您调用如下序列时,可重用机制才有意义:

//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];

在您的情况下,我将实现剪辑的方式(仅显示当前显示区域的注释)是:

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

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

于 2010-03-29T09:05:25.680 回答
0

不确定这是否会有所帮助,但您提到了由于加载约 60 个对象而导致的内存问题。有没有办法根据当前地图区域中心和当前地图区域跨度有条件地加载每个对象?

// :)

于 2009-10-12T15:34:57.550 回答