2010-07-30 13 views
6

Belirli konumlarda birden fazla daire bindirmesi olan bir haritayı gösteren bir iPhone uygulaması üzerinde çalışıyorum. 6'dan fazla daire eklediğimde ciddi bellek sorunlarına ve çökmelere yol açıyorum ve bunların hepsinin görülebildiğinden yeterince uzaklaşıyorum. Yalnızca 2 çevrede görünecek şekilde yakınlaştırdığımda, her şey yolunda. MKOverlay'ları kaldırdığımda her şey iyi çalışıyor.MKMapView'daki Birden Fazla MKOverlay, bellek uyarılarına yol açıyor

Bu davranışı tanıyan var mı?

Kaplamaları oluşturan kod. Bir NSMutableDictionary içinde bindirmeleri ileride başvurmak üzere (haritada bunları kaldırmak için muktedir ve çift bindirmeleri önlemek için) bindirme incelemeler serbest bırakır

#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; 
} 

Kod yapar

- (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]; 
     } 
    } 
} 

Kod saklamak kaplamayı önbellek

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

Meraklı bu ne oluyor bir iOS sürümü. Enstrümanlarda hafıza tüketimi artışını nerede görüyorsunuz? – Nick

+0

iOS 4.0 çalıştırıyorum. MKCircle sınıfı 4.0'da eklendi. Daha fazla test yaptım ve sadece iPhone 3G'de ciddi sorunlara yol açıyor gibi görünüyor. 3GS ve simülatör iyi çalışıyor. Enstrümanlarda herhangi bir ani artış görmüyorum, bunu araştırmak zorlaştırıyor. – rule

cevap

5

Aynı şeyi görüyorum. Ben daireler yerine MKPolylines çiziyorum, ama bende aynı problem var. 1 satır iyi çalışıyor, ancak birkaç tane eklemeye başladığımda ve haritayı hareket ettirmeyi denediğimde bellek uyarıları ile çöküyor. Kodumu yapıştırırdım, ama çizgi için yukarıdaki değişen daireyle hemen hemen aynı.

DÜZENLEME: Sorun, her bindirmenin yeni bir çekirdek animasyon katmanı oluşturduğu anlaşılıyor. Bir geçici çözüm burada var - https://devforums.apple.com/thread/48154?tstart=0 Ayrıca, bundan sonraki sürümünde

DÜZENLEME sabit olmalıdır bilinen bir hata olduğuna inanıyoruz. Geçici çözüm - "Oldukça API ama uygulama ile bir sorun değildir önerim elle birine bunları birleştirmek için şu an için geçici bir çözümdür Örneğin

, burada bir MultiPolygon ve ilgili görünümü uygulamak gibi uygulayabilirsiniz."

@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 
+0

Teşekkürler, ben bu işi deneyeceğim! – rule

+1

Bu hata bir iOS 4.x sürümünde hiç düzeltildi mi? –

+2

Evet, 4.1 – clarky