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