1

Я вызываю веб-службу, которая возвращает массив аннотаций в методе делегата, который я добавляю к своей карте с помощью метода addAnnotations для MKMapView. Все идет плавно, пока метод делегата не отправит сразу два массива (обычно около 150 мс - 500 мс), а затем я получаю EXC_BAD_ACCESS (code=1 address 0x20) на этой линии [kMap addAnnotations:tileArray]; - Это, похоже, проблема с памятью, но я не совсем уверен, что делать, как это или как изменить свой код, чтобы решить эту проблему.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]; 
         }]; 
    } 
} 

--- ------ Сложение ---------

Добавление в мой код из пользовательского ап в ответ на № 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

+1

@Rob этот ответ на вопрос, который вы ссылки (http://stackoverflow.com/a/8932791/2939977) действительно помогли, так как я получил некоторые недопустимые координаты, но я также вижу несколько утечек памяти, которые вы рассмотрели в своем ответе ниже. Я просматриваю их сейчас –

+0

Где находится 'kMap'? – jlehr

ответ

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», он, кажется, использует старый кадр, цвет и т. Д. - I отредактировал мой оригинальный вопрос, чтобы включить мой пользовательский код аннотации. –

+0

1. Справочник по инструментам re memory: см. Https://developer.apple.com/videos/wwdc/2012/?id=242, в котором подробно излагаются сведения о памяти, но в некоторых случаях он содержит некоторые интересные практические демонстрации. 2. Re 'transitionWithView', да, это заморозит представление (следовательно, мой« менее элегантный »комментарий), но если у вас продолжались проблемы с использованием памяти, это было что-то для рассмотрения. Если ваши проблемы исчезли, не беспокойтесь об этом. 3. Re dequeueing, пока ваша 'viewForAnnotation' правильно переконфигурирует аннотацию и аннотацию при повторном использовании, вы должны быть в порядке. – Rob

Смежные вопросы