NSTimer 对象不起作用(无法使用 NSTimer 自动刷新令牌)

NSTimer object doesn't work (can't refresh token automatically using NSTimer)

我的 NSTimer 对象不工作 - 它启动了,但没有触发。我尝试通过 scheduledTimerWithTimeInterval 方法自动刷新令牌。

这里是 Token 的代码 class:

//
//  Token.m
//  oauthdemoapp
//

#import "Token.h"
#import "ServerManager.h"

@implementation Token

+ (Token *) sharedInstance {
    static Token *token = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        token = [[Token alloc] init];
    });
    return token;
}

- (void)setAccessToken:(NSString *)accessToken {
    _accessToken = accessToken;
    [self runTheTimer];
}

#pragma mark -
#pragma mark Timer

- (void)runTheTimer {
    NSLog(@"timer started");
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(executeRefreshTokenRequest) userInfo:nil repeats:YES];
    self.timer = timer;

}

- (void)stopTheTimer {

}

#pragma mark -
#pragma mark Requests

- (void)executeRefreshTokenRequest {
    NSLog(@"timer fired");
    [[ServerManager sharedInstance] postForNewTokenWithRefreshToken:self onSuccess:^(Token *updatedToken) {
        NSLog(@"%@", self.accessToken);
        NSLog(@"%@", updatedToken.accessToken);
    } onFailure:^(NSError *error) {
        NSLog(@"%@", [error localizedDescription]);
    }];

}


@end

当我在授权用户时在此处保存访问令牌时,计时器开始计时。但是它不会触发开始倒计时和 运行 刷新令牌请求。

不过,我的全局任务是自动刷新令牌 - 它响应访问令牌、时间间隔 60 秒和刷新令牌。也许你可以建议更好的解决方案。

谢谢

定时器与 运行 循环协同工作。也许您的问题在于 运行 循环。您可以考虑使用 dispatch_source.

使用 grand central dispatch 解决了问题。

我在 class 中声明块方法:

dispatch_source_t CreateLocationTimerDispatch(double interval, dispatch_queue_t queue, dispatch_block_t block) {
    dispatch_source_t timerForLocationRefresh = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    if (timerForLocationRefresh) {
        dispatch_source_set_timer(timerForLocationRefresh, dispatch_time(DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), interval * NSEC_PER_SEC, (1ull * NSEC_PER_SEC) / 10);
        dispatch_source_set_event_handler(timerForLocationRefresh, block);
        dispatch_resume(timerForLocationRefresh);
    }
    return timerForLocationRefresh;
}

class 局部变量:

dispatch_source_t _timerForLocationRefresh;
static double SECONDS_TO_FIRE = 1800.f; // time interval lengh in seconds 1800

定时器启动方法:

- (void)startTimer {
    // second timer
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    _timerForLocationRefresh = CreateLocationTimerDispatch(SECONDS_TO_FIRE, queue, ^{

        // do smth
    });
}

停止计时器的方法:

- (void)cancelTimer {
    if (_timerForLocationRefresh) {
        dispatch_source_cancel(_timerForLocationRefresh);
        _timerForLocationRefresh = nil;
    }
}