MKMapView上的多个MKOverlay会导致内存警告 [英] Multiple MKOverlays on a MKMapView lead to memory warnings

查看:104
本文介绍了MKMapView上的多个MKOverlay会导致内存警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一款iPhone应用,可以在某些位置显示包含多个圆形叠加层的地图。
当我添加超过6个圆圈时,我遇到严重的内存问题和崩溃,我缩小到足以让它们全部可见。
当我放大以便只能看到2个圆圈时,一切都很好。当我删除MKOverlay时,一切正常。

I'm working on an iPhone app that shows a map with multiple circle overlays on certain locations. I'm running into serious memory issues and crashes when I add more than 6 circles and I zoom out far enough that they are all visible. When I zoom in such that only 2 circles are visible, all is fine. When I remove the MKOverlays, everything works fine.

是否有人认识到这种行为?

Anyone who recognizes this behavior?

创建覆盖。我将叠加层存储在NSMutableDictionary中以供将来参考(能够从地图中删除它们并防止双重叠加)

Code that creates the overlays. I store the overlays in a NSMutableDictionary for future reference (to be able to remove them from the map and to prevent double overlays)

- (void)updateMarkersForZones:(NSArray *)zones {
    NSLog(@"MapViewController: Update Markers");
    // For each zone, show a marker
    for (Zone* zone in zones) {
        NSString *keyMarker = [NSString stringWithFormat:@"%d-marker", zone.id];

        MKCircle *circle = [overlayCache objectForKey:keyMarker];
        if (circle == nil) {
            // draw the radius circle for the marker
            double radius = MAX(zone.markerRadius * 1.0, 1.0);
            circle = [MKCircle circleWithCenterCoordinate:zone.location radius:radius];
            [mapView addOverlay:circle];
            // store the circle in a cache for future reference
            [overlayCache setObject:circle forKey:keyMarker];
        }
    }
}

制作叠加视图的代码

#pragma mark -
#pragma mark MKMapViewDelegate
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay{
     MKCircleView *circleView = [[[MKCircleView alloc] initWithCircle:overlay] autorelease];
    circleView.lineWidth = 1.0;
    circleView.strokeColor = [UIColor redColor];
    return circleView;
}

释放重叠缓存的代码

- (void)dealloc {
    [overlayCache release];
    [mapView release];
    [super dealloc];
}


推荐答案

我看到同样的事情发生。我正在绘制MKPolylines而不是圆圈,但我有完全相同的问题。 1行工作正常,但当我开始添加几个并尝试移动地图时,它会因内存警告而崩溃。我会粘贴我的代码,但它几乎与上面的行更改相同。

I am seeing the same thing happen. I am drawing MKPolylines instead of circles, but I have exactly the same problem. 1 line works fine, but when I start to add several and try moving the map around it crashes with memory warnings. I'd paste my code, but it is pretty much identical to the above changing circle for line.

编辑:问题似乎是每个叠加层都会创建一个新的核心动画层。这里有一个解决方法 - https://devforums.apple.com/thread/48154? tstart = 0 此外,我认为这是一个已知的错误,应该在下一个版本中修复

the problem seems to be that each overlay creates a new core animation layer. there is a workaround here - https://devforums.apple.com/thread/48154?tstart=0 Also, I believe this is a known bug that should be fixed in the next release

编辑:解决方法 - 它不是一个API的问题,而不是实现。我建议手动将它们合并为一个是暂时的解决方法。

the workaround - "It isn't a problem with the API but rather the implementation. My suggestion to manually consolidate them into one is a workaround for the moment.

例如,以下是如何实现MultiPolygon和相应的观点:

For example, here's how you could implement a MultiPolygon and corresponding view:"

    @interface MultiPolygon : NSObject <MKOverlay> {
    NSArray *_polygons;
    MKMapRect _boundingMapRect;
}

- (id)initWithPolygons:(NSArray *)polygons;
@property (nonatomic, readonly) NSArray *polygons;

@end

@implementation MultiPolygon

@synthesize polygons = _polygons;

- (id)initWithPolygons:(NSArray *)polygons
{
    if (self = [super init]) {
        _polygons = [polygons copy];

        NSUInteger polyCount = [_polygons count];
        if (polyCount) {
            _boundingMapRect = [[_polygons objectAtIndex:0] boundingMapRect];
            NSUInteger i;
            for (i = 1; i < polyCount; i++) {
                _boundingMapRect = MKMapRectUnion(_boundingMapRect, [[_polygons objectAtIndex:i] boundingMapRect]);
            }
        }
    }
    return self;
}

- (void)dealloc
{
    [_polygons release];
    [super dealloc];
}

- (MKMapRect)boundingMapRect
{
    return _boundingMapRect;
}

- (CLLocationCoordinate2D)coordinate
{
    return MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMidX(_boundingMapRect), MKMapRectGetMidY(_boundingMapRect)));
}

@end



@implementation MultiPolygonView

- (CGPathRef)polyPath:(MKPolygon *)polygon
{
    MKMapPoint *points = [polygon points];
    NSUInteger pointCount = [polygon pointCount];
    NSUInteger i;

    if (pointCount < 3)
        return NULL;

    CGMutablePathRef path = CGPathCreateMutable();

    for (MKPolygon *interiorPolygon in polygon.interiorPolygons) {
        CGPathRef interiorPath = [self polyPath:interiorPolygon];
        CGPathAddPath(path, NULL, interiorPath);
        CGPathRelease(interiorPath);
    }

    CGPoint relativePoint = [self pointForMapPoint:points[0]];
    CGPathMoveToPoint(path, NULL, relativePoint.x, relativePoint.y);
    for (i = 1; i < pointCount; i++) {
        relativePoint = [self pointForMapPoint:points[i]];
        CGPathAddLineToPoint(path, NULL, relativePoint.x, relativePoint.y);
    }

    return path;
}

- (void)drawMapRect:(MKMapRect)mapRect
          zoomScale:(MKZoomScale)zoomScale
          inContext:(CGContextRef)context
{
    MultiPolygon *multiPolygon = (MultiPolygon *)self.overlay;
    for (MKPolygon *polygon in multiPolygon.polygons) {
        CGPathRef path = [self polyPath:polygon];
        if (path) {
            [self applyFillPropertiesToContext:context atZoomScale:zoomScale];
            CGContextBeginPath(context);
            CGContextAddPath(context, path);
            CGContextDrawPath(context, kCGPathEOFill);
            [self applyStrokePropertiesToContext:context atZoomScale:zoomScale];
            CGContextBeginPath(context);
            CGContextAddPath(context, path);
            CGContextStrokePath(context);
            CGPathRelease(path);
        }
    }
}

@end

这篇关于MKMapView上的多个MKOverlay会导致内存警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆