2012-06-02 3 views
0

Хорошо .. вот весь сценарийEXC_BAD_ACCESS используя [UIView animateWithDuration: анимация: завершающий]

Концепции, чтобы показать несколько заказов на экране пользователя будучи в состоянии ползунка влево или вправо, чтобы увидеть следующую. После того, как заказ принят или отклонен, вид заказа скользит вниз и заменяется рядом с ним или предыдущим, если заказ завершен.

У меня есть вид в виде табулатуры, который содержит простой UIScrollView и пару кнопок (Accept & Decline). В ViewDidLoad готовлюсь массив Orders, инициализировать ViewControllers (равные объема заказов) с СИБ файлов и добавить взгляды этих этих ViewController к в ScrollView и указан размер содержимого в Scrollview в и т.д .. (для вертикальной & горизонтальной прокруткой)

Когда пользователь отбирает AcceptButton, выполняется анимация, сдвигая видимый вид в UIScrollView вниз, а затем удаляя его из супер-представления.

Код анимации выполняется следующим образом.

BOOL lastPage = NO; 
    BOOL ordersEmpty = NO; 
    if (self.views.count == 1){ 
     ordersEmpty = YES; 
     lastPage = YES; 
    } 

    UIViewController *controller2; 
    if (self.views.count == page+1 && !ordersEmpty){ 
     lastPage = YES; 
     controller2 = [self.views objectAtIndex:page-1]; 
    } else if (!ordersEmpty){ 
     controller2 = [self.views objectAtIndex:page+1]; 
    } 
    [UIView animateWithDuration:1.5 animations:^{ 
     CGRect frame = controller.view.frame; 
     frame.origin.y = frame.size.height + 100; 
     controller.view.frame = frame; 

     if (lastPage == NO){ 
      CGRect frame2 = controller2.view.frame; 
      frame2.origin.x = frame.origin.x; 
      controller2.view.frame = frame2; 
     }else{ 
      // [self.scrollView scrollRectToVisible:controller2.view.frame animated:YES]; 
     } 

    } completion:^(BOOL value){ 
     [controller.view removeFromSuperview]; 
     [self.views removeObject:controller]; 
     totalPages.text = [NSString stringWithFormat:@"%i", self.views.count]; 
     // currentPage.text = [NSString stringWithFormat:@"%i", 
     self.pageControl.numberOfPages = self.views.count; 
     if (lastPage && !ordersEmpty){ 
      [self.scrollView scrollRectToVisible:controller2.view.frame animated:YES]; 
      lastPageMoving = YES; 
     }else if (ordersEmpty){ 
      UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 30)]; 
      label.text = @"There are currently no notifications"; 
      label.textAlignment = UITextAlignmentCenter; 
      label.center = CGPointMake(self.scrollView.frame.size.width/2, self.scrollView.frame.size.height/3); 
      [self.scrollView addSubview:label]; 
      [label release]; 
      ofPages.text = @""; 
      totalPages.text = @""; 
      currentPage.text = @""; 
      self.scrollView.contentSize = CGSizeMake(320, 267); 
     } 

     int i = 0; 
     for (UIViewController *c in self.views) 
     { 
      c.view.frame = CGRectMake(self.scrollView.frame.size.width * i, 0, c.view.frame.size.width, c.view.frame.size.height); 
      i++; 
     } 

     if (controller2 != nil) 
     { 
      if ([controller2 isKindOfClass:[CancelledController class]]) { 
       self.acceptButton.hidden = YES; 
       [self.declineButton setTitle:@"Close" forState:UIControlStateNormal]; 
       [self.declineButton setTitle:@"Close" forState:UIControlStateHighlighted]; 
      }else{ 
       self.acceptButton.hidden = NO; 
       [self.declineButton setTitle:@"Decline" forState:UIControlStateNormal]; 
       [self.declineButton setTitle:@"Decline" forState:UIControlStateHighlighted]; 
      } 
     } 
    }]; 

Анимация работает отлично и вид удалено, однако высвобождены

когда последний вид принимаются сбои приложений с EXC_BAD_ACCESS точно [UIView animateWithDuration: анимация: завершение] вызов метода.

NSZombies не обнаруживает точную точку утечки/причина ..

После обширных исследований, я думаю, что это может быть связано с использованием блоков .. управление памятью отлично, потому что если бы я overreleasing ничего, NSZombies указывало бы Это.

(КОД работает отлично имитатор ХОТЯ - НИКАКИХ ОШИБОК ЧТО ТАК ВСЕГДА)

я сделал видео, чтобы продемонстрировать, как работает анимация .. Это имитатора поэтому не ошибка здесь, однако, когда я запускаю его на устройство, приложение аварийно завершает работу, как только я нажимаю кнопку закрытия.

Интересная вещь, если я первый закрыть второй заказ и принять первый заказ после, код работает отлично тоже = (очень запутанным Действительно .. !!

http://www.mediafire.com/?w1up9g9u6w0ucrn

Проект нацелен на IOS 4,0

+0

Устройство и симулятор работает 5.0.1 и 5.1 iOS соответственно .. !! XCode - 4.3, а Base IOS SDK - 5.1 – tGilani

+2

Используйте '__unsafe_unretained MyClass * weakSelf = weakSelf;' затем замените 'self' внутри блоков на weakSelf, потому что ссылка на self будет сбой, если self будет выпущен, пока блок все еще работает (также имеет смысл не сохранять что вы не владеете). Это просто хорошая практика, не обязательно ошибка, которую вы описываете. EXC_BAD_ACCESS не всегда поступает из сообщения с недопустимым указателем, иногда это C-библиотека внизу (не знаю, если это так). Проводка в качестве комментария, потому что я не прочитал все это или не знаю, в чем проблема. – Jano

ответ

2

Вы можете начать с изменения объявления UIViewController *controller2 в UIViewController *controller2 = nil;, то это хорошая идея, чтобы использовать только свойства, так что линии:

[controller.view removeFromSuperview]; 
[self.views removeObject:controller]; 

будет заменен вызовом методов доступа этого свойства, и вы, и мы будем иметь точную идею, если ivar controller сохранен или нет. Это справедливо для всех других иваров, которые вы используете: lastPageMoving, ofPages, totalPages, currentPage и т. Д. - просто измените их на свойства и убедитесь в правильном управлении памятью.

+0

Ok .. Отлично .. Преобразуя все локальные переменные в свойства экземпляра контроллера, кажется, что ошибка исчезла .. спасибо .. Но мне действительно интересно, в чем была проблема. = / – tGilani

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