MKMapView有多个覆盖内存的问题

似乎有一个覆盖和MapKit的“问题”。 与注释不同的是,叠加层不会被重用,因此添加多个叠加层会导致真实设备上的内存问题。 我有这个问题多次。 所以我的问题是,如何重新使用MKOverlay,从而提高MapKit覆盖层的性能?

对此的回答不是“重用”,而是将它们全部绘制到一个MKOverlayView ,然后在地图上绘制。

在地图上绘制时,多个MKPolygonsMKOverlays等会导致大量的内存使用。 这是由于MapKit没有重用覆盖。 由于注释具有reuseWithIdentifier ,所以叠加不会。 每个叠加层MKOverlayView在地图上以覆盖graphics式创build一个新的图层,作为MKOverlayView 。 以这种方式,内存使用率将会上升得相当快,地图使用变成了……让我们说呆滞到几乎不可能。

因此,有一个解决方法:您可以将所有MKOverlays添加到一个MKOverlayView ,而不是单独绘制每个覆盖MKOverlayView 。 这样你实际上只创build一个MKOverlayView ,因此不需要重用。

这是MKPolygons的解决方法,但对MKCircles等其他人应该没什么不同。

创build一个类: MultiPolygonNSObject子类)

MultiPolygon.h

 #import <MapKit/MapKit.h> //Add import MapKit @interface MultiPolygon : NSObject <MKOverlay> { NSArray *_polygons; MKMapRect _boundingMapRect; } - (id)initWithPolygons:(NSArray *)polygons; @property (nonatomic, readonly) NSArray *polygons; @end 

MultiPolygon.m

 @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; } - (MKMapRect)boundingMapRect { return _boundingMapRect; } - (CLLocationCoordinate2D)coordinate { return MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMidX(_boundingMapRect), MKMapRectGetMidY(_boundingMapRect))); } @end 

现在创build一个类: MultiPolygonViewMKOverlayPathView子类)

MultiPolygonView.h

 #import <MapKit/MapKit.h> @interface MultiPolygonView : MKOverlayPathView @end 

MultiPolygonView.m

 #import "MultiPolygon.h" //Add import "MultiPolygon.h" @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 

对我们来说,在您的ViewController中导入MultiPolygon.hMultiPolygonView.h

从全部创build一个多边形:作为一个例子,我有一个多边形数组: polygonsInArray

 MultiPolygon *allPolygonsInOne = [[MultiPolygon alloc] initWithPolygons:polygonsInArray]; 

将allPolygonsInOne添加到mapView:

 [mapView addOverlay:allPolygonsInOne]; 

还要改变你的viewForOverlay方法:

 -(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay { if ([overlay isKindOfClass:[MultiPolygon class]]) { MultiPolygonView *polygonsView = [[MultiPolygonView alloc] initWithOverlay:(MultiPolygon*)overlay]; polygonsView.fillColor = [[UIColor magentaColor] colorWithAlphaComponent:0.8]; polygonsView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.8]; polygonsView.lineWidth = 1; return polygonsView; } else { return nil; } } 

这大大减less了mapView上多个叠加层的内存使用量。 您现在没有重用,因为只绘制了一个OverlayView 。 所以不需要重复使用。