1

我打電話給Web服務,該服務返回一個代理方法中的註釋數組,該方法將使用addAnnotations方法添加到我的地圖中,作爲MKMapView。一切順利順順當當,直到委託方法發送快速連續兩個數組(通常約150毫秒 - 500毫秒),然後我得到的這條線[kMap addAnnotations:tileArray];一個EXC_BAD_ACCESS (code=1 address 0x20) - 這似乎是一個記憶的問題,但我真的不知道該怎麼做如何或如何改變我的代碼來解決它。EXC_BAD_ACCESS在MKMapView中添加註釋

這裏是委託方法

-(void)rebelBaseManager:(RebelBaseManager *)manager didUpdateTileHour:(NSArray *)tileArray boundaryBreak:(NSString *)breakType atTileLevel:(int)callTileLevel { 

if (timerStarted == NO) { 

    [self startTimer]; 
} 

//Check for tileLevel in case multiple calls were made at different tile levels 
if (tileLevel == callTileLevel) { 

    [kMap addAnnotations:tileArray]; 
    [HourInMap addObjectsFromArray:tileArray]; 
} 
} 

我還添加了一個方法,讓我的動畫去除註釋這是在以下情況下,它的確與衆不同:

- (void)removeAnnotationsWithFade:(NSArray *)annotations animated:(BOOL)shouldAnimate { 

if (!shouldAnimate) 
    [self removeAnnotations:annotations]; 
else { 

    for (HourAnnotation *annotation in annotations) { 

     MKAnnotationView *annotationView = [self viewForAnnotation:annotation]; 

     [UIView animateWithDuration:2 
         animations:^{ 

          annotationView.alpha =0; 

         }completion:^(BOOL finished) { 

          [self removeAnnotation:annotation]; 
         }]; 
    } 
} 

--- ------ ADDITION ---------

在我的代碼中添加一個自定義的回覆下面Rob的回答#3中的符號。

- (id)initWithFrame:(CGRect)frame 
    { 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code 
    } 
    return self; 
    } 


    - (id)initWithHourAnnotation:(HourAnnotation *)hourAnnotation reuseIdentifier:(NSString *)reuseIdentifier { 

    CGRect myFrame = self.frame; 
    myFrame.size.width = hourAnnotation.frameSize; 
    myFrame.size.height = hourAnnotation.frameSize; 

    self = [super initWithFrame:myFrame]; 
    //When I use this here I seem to get the frame and color of the old annotation displayed 
    //self = [super initWithAnnotation:velocityAnnotation reuseIdentifier:reuseIdentifier]; 
    if (self) 
    { 

     self.layer.cornerRadius = self.frame.size.width/2; 
     self.clipsToBounds = YES; 
     [self setBackgroundColor:[UIColor clearColor]]; 

     NSArray *alphaValue = [[NSArray alloc]initWithArray:[self alphaForTileLevel]]; 


     self.fillColor = [UIColor colorWithHue:hourAnnotation.color saturation:.06 brightness:.23 alpha:[[alphaValue objectAtIndex:hourAnnotation.tileLevel-1]doubleValue]]; 
     self.strokeColor = [UIColor colorWithHue:hourAnnotation.color saturation:.06 brightness:.23 alpha:.35]; 


     self.enabled = NO; 
     self.canShowCallout = NO; 
     self.userInteractionEnabled = NO; 

    } 

    return self; 

    } 


    - (void)drawRect:(CGRect)rect 
{ 
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect]; 
    [self.fillColor set]; 
    [path fill]; 
    [self.strokeColor set]; 
    [path setLineWidth:2.0f]; 
    [path stroke]; 
} 
+1

可能下面的副本,雖然不完全清楚:http://stackoverflow.com/questions/4202510/mkmapview-crashing-with-exc-bad-access – Rob 2014-08-28 12:56:13

+1

@Rob這個答案的問題,你參考(http://stackoverflow.com/a/8932791/2939977)沒有幫助,因爲我得到了一些無效的座標,但我也看到你在下面你的答案解決的幾個內存泄漏。我正在研究那些現在的 – 2014-08-28 20:43:31

+0

'kMap'定義在哪裏? – jlehr 2014-08-28 21:23:15

回答

2

一對夫婦的想法。

  1. 你沒有顯示出你在哪裏打電話給removeAnnotationsWithFade。我們必須假設你正在移除適當的模型對象。使用儀器確認你沒有泄漏到任何地方。

  2. 如果淡入拆卸時,但不褪色不崩潰的應用程序崩潰,那麼你可以考慮重構該代碼。具體來說,您的動畫代碼實際上並沒有刪除舊的動畫,直到完成塊(即兩秒鐘後)。因此,您將繼續使用比所需時間更長的舊註釋。如果註釋快速而激烈地出現,您可能會遇到內存問題。

    例如,如果您使用transitionWithView:mapView而不是直接刪除註釋,則可能會更快地釋放與舊註釋關聯的內存。這是一個不太雅緻的動畫,但可能是「足夠好」,並儘量減少你的內存使用峯值:

    // this will immediately remove the annotations, but animate the fading of the transition 
    
    [UIView transitionWithView:self.mapView duration:2.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ 
        [self.mapView removeAnnotations:annotations]; 
    } completion:nil]; 
    
    // presumably remove the annotations from your array, too 
    
  3. 是您viewForAnnotation離隊的老批註意見,並僅實例化新的,如果它不能出隊一箇舊的,或者它總是實例化新的?像這樣的東西可能也有助於控制峯值內存使用率。

+0

謝謝你在這裏的努力......一些評論1)注意---我對xCode非常陌生---你會爲儀器推薦任何教程? 2)我嘗試了'transitionWithView:mapView',並在淡入淡出完成時將整個地圖與註釋一起凍結。偉大的想法只會造成波濤洶涌的體驗。 3)我在我的一些自定義註釋中,但並非所有我正在調整框架大小,顏色和做一些自定義繪圖,當我使用'reuseidentifier'它似乎使用舊的框架,顏色等。編輯我的原始問題以包含我的自定義註釋代碼。 – 2014-08-28 21:13:17

+0

1.樂器教程重新記憶:請參閱https://developer.apple.com/videos/wwdc/2012/?id=242,其中深入探討了有關記憶的許多細節,但後面還包含了一些很好的實用演示。 2.重新'transitionWithView',是的,它會凍結視圖(因此,我的「不那麼優雅」的評論),但如果你繼續有內存使用問題,這是需要考慮的事情。如果你的問題消失了,不要擔心。 3.重新出隊,只要你的viewForAnnotation在重用時適當地重新配置註解和註解視圖,你應該在那裏確定。 – Rob 2014-08-28 21:30:59