аннулирование таймера блокирует мое приложение

#iphone #nstimer

#iPhone #nstimer

Вопрос:

Я сделал следующее:

файл заголовка

  NSTimer *timer1;
 NSTimer *timer2;
  

файл реализации

 - (void)viewDidLoad
{
    if(!timer1)
        timer1 = [NSTimer scheduledTimerWithTimeInterval:30.0 target: self selector: @selector(repeatRequest) userInfo: nil repeats: YES];

    if(!timer2)
        timer2 = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    // Release any retained subviews of the main view.

    [timer1 invalidate];
    [timer2 invalidate];

}
  

Поэтому, когда я покидаю текущее представление, эти две строки приводят к сбою моего приложения:

  [timer1 invalidate];
        [timer2 invalidate];
  

У кого-нибудь есть идеи, почему?Или кто-нибудь знает какой-либо другой способ остановить таймер, когда я покидаю текущее представление?Спасибо

РЕДАКТИРОВАТЬ: timer2 вызывает этот метод:

 - (void) repeatRequest{
    NSLog(@"backgroundRequest");
    [NSThread detachNewThreadSelector:@selector(backgroundRequest) toTarget:self withObject:nil];
}
  

что делает ASIHTTPRequest на стороне сервера.

теперь я сохранил только:

 [timer1 invalidate];
  

и он больше не блокируется … но что я делаю с timer2?

Комментарии:

1. Отправляют ли таймеры сообщения до исчезновения представления?

Ответ №1:

эти 2 строки на самом деле не должны быть плохими — на случай, если вы освободите viewcontroller и, следовательно, представление исчезнет.

если вы можете вернуться к своему представлению, viewDidLoad НЕ вызывается. в этом случае timer1 и timer2, как сказал логанкаутрелл, зависают.

итак, что вы хотите попробовать, это:

  - (void)viewWillDisappear:(BOOL)animated
 {
     [super viewWillDisappear:animated];

     [timer1 invalidate];
     timer1 = nil;

     [timer2 invalidate];
     timer2 = nil;
 }
  

а также перемещение

   if(!timer1)
         timer1 = [NSTimer scheduledTimerWithTimeInterval:30.0 target: self selector: @selector(repeatRequest) userInfo: nil repeats: YES];

   if(!timer2)
         timer2 = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
  

к вашему

    -(void)viewDidAppear:(BOOL)animated
  

тогда это не должно вас беспокоить.

Комментарии:

1. попробуйте: if(timer1){[timer1 недействителен]; timer1= nil;} то же самое для timer2 ? (не знаю другого кода, который у вас всегда есть)

2. можете ли вы гарантировать, что вызывается viewWillDisappear? это для UINavigationControllers и некоторых других, а не для всех типов VC iirc. вместо этого попробуйте viewDidDisapper, если это просто пользовательский интерфейс.

3. да, я отправил сообщение. и оно вызывается. Оно блокируется, потому что я аннулирую таймер. Если я прокомментирую эти строки, это сработает!

4. можете ли вы предоставить полную информацию о том, что означает «блокировка» в вашем случае? ошибка? сбой? сообщение? или оно просто зависает?

5. происходит сбой. Появляется сигнал EXC_BAD_ACCESS!

Ответ №2:

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

Комментарии:

1. дело в том, что даже если я аннулирую таймер… метод, запускаемый таймером, все еще вызывается. есть идеи, почему?