NSTimer не запускает селектор - PullRequest
28 голосов
/ 29 марта 2012

В ios5.0 с ARC в моем rootviewcontroller я вызываю метод в объекте диспетчера безопасности, который удерживается делегатом приложения.В этом методе я устанавливаю таймер, как показано ниже:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self 
                                       selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 

Однако, это никогда не запускает селектор, т.е.updateModel: никогда не вызывается.Что может быть не так?Есть ли еще более эффективный способ сделать это без использования NStimer?

Ответы [ 4 ]

116 голосов
/ 07 августа 2013

Также может быть проблема с многопоточностью:

, если

[NSThread isMainThread]

имеет значение false, запустите таймер следующим образом:

dispatch_async(dispatch_get_main_queue(), ^{
        timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
    })
13 голосов
/ 29 марта 2012

Вы, кажется, немного перепутали с вашей переменной таймера.

Вы инициализируете новый таймер, но на самом деле вы его не используете.Вы хотите использовать инициализированный вами таймер или ApplicationDelegate.timer?

Вот два возможных решения.

Вариант первый (при условии, что у вас есть экземпляр класса с именем ApplicationDelegateи что он имеет свойство таймера):

ApplicationDelegate.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes];

Вариант второй:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
8 голосов
/ 11 октября 2012

Я улавливаю ту же проблему и запускаю таймер в основной очереди, чтобы решить ее:

[NSURLConnection sendAsynchronousRequest:request queue:_operationQueue
    completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
         [self loopUpUpdateStart];
}];

-(void)loopUpUpdateStart{
    dispatch_async(dispatch_get_main_queue(), ^{

        _loopTimerForUpRevision = 
          NSTimer scheduledTimerWithTimeInterval: kNetworkLoopIntervalUpRev
                                          target: self
                                        selector: @selector(myCoolMethod)
                                        userInfo: nil
                                         repeats: YES];
        TRACE(@"Start Up updates");
    });
}
7 голосов
/ 29 марта 2012

В этой строке есть несколько проблем:

[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes]; 

Во-первых, это вообще не нужно. -scheduledTimerWithTimeInterval:... уже добавляет таймер в цикл запуска. Вам не нужно добавлять его снова.

Во-вторых, локальная переменная timer не связана со свойством ApplicationDelegate.timer (которое предположительно nil на данный момент).

Если вы так много разговариваете с делегатом приложения, что создали нечто, называемое ApplicationDelegate (глобальный «макрос»), вы слишком много говорите с ним. Делегат приложения является делегатом приложения; он помогает запускать, останавливать приложение и реагировать на системные события. Делегат приложения не является местом для хранения глобальных переменных. В любом случае, таймер - это не та вещь, которую вы могли бы извлечь из другого объекта.

...