2014-02-07 3 views
0

У меня раньше был один NSTimer, который отлично работает. Я добавил еще один NSTimer в мою runloop, так как теперь мне нужно много раз вызывать две функции после задержки. Обе функции имеют различную задержку. Мой код приведен ниже.Второй NSTimer не работает?

self.now = [NSDate date] ; 
    self.timer = [[NSTimer alloc] initWithFireDate:self.now 
              interval:500 
              target:self 
              selector:@selector(Func1) 
              userInfo:nil 
              repeats:YES] ; 

    self.runLoop = [NSRunLoop currentRunLoop]; 
    [runLoop addTimer:self.timer forMode:NSDefaultRunLoopMode]; 
    [self.runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10000]]; 


    //Second timer start here.its not working.The function 'func2' is not getting called 

    self.now = [NSDate date] ; 
    self.timer = [[NSTimer alloc] initWithFireDate:self.now 
              interval:60 
              target:self 
              selector:@selector(Func2) 
              userInfo:nil 
              repeats:YES] ; 

    self.runLoop = [NSRunLoop currentRunLoop]; 
    [runLoop addTimer:self.timer forMode:NSDefaultRunLoopMode]; 
    [self.runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10000]]; 

NSTimer Первый по-прежнему работает, но второй NSTimer не работает.

ответ

2

Вы должны объявить второе свойство NSTimer. В настоящее время вы перезаписать свой первый таймер при выполнении этого

self.timer = [[NSTimer alloc] initWithFireDate:self.now 
             interval:60 
             target:self 
             selector:@selector(Func2) 
             userInfo:nil 
             repeats:YES] ; 

Declare Timer2 в своих аналогах интерфейса к вашей декларации таймера и использование self.timer2 для хранения второго таймера.

+1

Если вы все еще видите проблемы после принятия исправления, предложенного Фолькером, я бы заглянул в ваши вызовы runloop. Это не выглядит правильным.Вы должны настроить два таймера, добавив их в runloop, и это все (если это основной поток). Если это не так, и вы должны сами запустить цикл выполнения, я думаю, что это должно быть сделано в цикле while. –

+0

@ Volker его все еще не работает – zzzzz

+0

См. Ответ Роба для решения другой проблемы в вашем коде – Volker

3

Хотя это не хорошо, что вы переписываете свои свойства (это не влияет на способность таймеров запускаться индивидуально, но это просто означает, что вы отбрасываете свою ссылку на первый таймер при установке второго таймер, и, таким образом, вы теряете возможность invalidate первого таймера, если вам когда-нибудь понадобится это сделать), ключевой проблемой является то, что вы вызываете runUntilDate. Это не нужно делать, и первый runUntilDate предотвращает создание второго таймера, поскольку viewDidLoad не будет действовать после первого вызова runUntilDate.

Так что удалите оба звонка runUntilDate и оба таймера будут работать нормально. Используйте разные свойства, чтобы сохранить ссылку на два таймера, если вы хотите сохранить ссылку на оба, чтобы вы могли индивидуально указать invalidate, если и когда они вам больше не нужны. (И это важно, что вы invalidate их, когда они больше не нужны, потому что они поддерживают сильную ссылку на self, что означает, что у вас есть «сильный опорный цикл».)


Вы могли бы упростить пример кода:

NSDate *date = [NSDate date]; 

self.timer1 = [[NSTimer alloc] initWithFireDate:date 
             interval:500 
             target:self 
             selector:@selector(method1:) 
             userInfo:nil 
             repeats:YES]; 

[[NSRunLoop currentRunLoop] addTimer:self.timer1 forMode:NSRunLoopCommonModes]; 

self.timer2 = [[NSTimer alloc] initWithFireDate:date 
             interval:60 
             target:self 
             selector:@selector(method2:) 
             userInfo:nil 
             repeats:YES]; 

[[NSRunLoop currentRunLoop] addTimer:self.timer2 forMode:NSRunLoopCommonModes]; 

Или, если вам действительно не нужны NSRunLoopCommonModes, вы можете просто сделать:

self.timer1 = [NSTimer scheduledTimerWithTimeInterval:500 
               target:self 
              selector:@selector(method1:) 
              userInfo:nil 
               repeats:YES]; 

self.timer2 = [NSTimer scheduledTimerWithTimeInterval:60 
               target:self 
              selector:@selector(method2:) 
              userInfo:nil 
               repeats:YES]; 

И заметьте, я с помощью методов с параметром (отсюда и толстой кишки с помощью переключателя):

- (void)method1:(NSTimer *)timer 
{ 
    // do whatever 
} 

- (void)method2:(NSTimer *)timer 
{ 
    // do whatever 
} 
+0

Мне нужно запустить оба таймера навсегда и нужно запускать их повторно. Как я могу это сделать без rununtildate? – zzzzz

+0

@Worker Просто создайте таймеры и удалите 'runUntilDate', и они будут работать вечно (или, точнее, до тех пор, пока вы не назовете' invalidate' для соответствующих таймеров). – Rob

+0

это не работает. Приложение рушится. – zzzzz

0

На самом деле runUntilDate заставит приложение, чтобы продолжать работать таймер и операторы после этого не будет выполнена. Попробуйте это:

self.now = [NSDate date] ; 
self.timer = [[NSTimer alloc] initWithFireDate:self.now 
             interval:500 
             target:self 
             selector:@selector(Func1) 
             userInfo:nil 
             repeats:YES] ; 

self.runLoop = [NSRunLoop currentRunLoop]; 
[runLoop addTimer:self.timer forMode:NSDefaultRunLoopMode]; 


//Second timer start here.its not working.The function 'func2' is not getting called 

self.now = [NSDate date] ; 
self.timer = [[NSTimer alloc] initWithFireDate:self.now 
             interval:60 
             target:self 
             selector:@selector(Func2) 
             userInfo:nil 
             repeats:YES] ; 

self.runLoop = [NSRunLoop currentRunLoop]; 
[runLoop addTimer:self.timer forMode:NSDefaultRunLoopMode]; 

Даже если вы используете один и тот же timer переменную для обоих таймеров, он будет работать. Но, как указано в других ответах, вы теряете возможность аннулировать первый таймер. Просто закомментируйте заявления runUntilDate в обоих местах.

0

Объявить второе свойство для ваших таймеров - не решение. Вам просто нужно аннулировать старый таймер и назначить новый в основном потоке, и он будет работать! попробуйте следующее:

dispatch_async(dispatch_get_main_queue(), ^{ 
    _timer = [NSTimer scheduledTimerWithTimeInterval:interval 
                target:self 
                selector:@selector(function:) 
                userInfo:nil 
                repeats:YES]; 
    [_timer fire]; 
    }); 
Смежные вопросы