如果能让线程在后台一直运行也可以解决这个问题。前提是你要在应用中设置支持相关的操作。这样显得有些杀鸡用牛刀。
我的思路:当应用进入后台的时候记录下当前的时间A,进入前台后再记录当前的时间B,计算他们的时间差,然后再用倒计时剩下的时间减去这个时间差。结果大于0就继续倒计时,否则就结束倒计时。
代码如下:
@interface LoginVC ()
@property (weak, nonatomic) IBOutlet UIButton *getCheckMarkBtn;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) NSInteger timeNum;//60s
@property (nonatomic, assign) long long int backTime;//后台时间
@property (nonatomic, assign) long long int forgTime;//前台时间
@end
@implementation LoginVC
- (void)viewDidLoad
{
[super viewDidLoad];
_timeNum = 60;
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[_timer invalidate];//之前是放在viewWillDisappear:里面的,上面的方法在右滑动即将pop到上一个控制器但是未pop的时候就执行了
_timer = nil; //如果此时不pop还是在当前界面 但是定时器就被释放了,所以不能放在viewWillDisappear:方法中
}
- (void)daojishi
{
_timeNum--;
[_getCheckMarkBtn setTitle:[NSString stringWithFormat:@"还剩%ld秒", (long)_timeNum] forState:UIControlStateNormal];
if (_timeNum <= 0) {
[_getCheckMarkBtn setTitle:@"重新获取" forState:UIControlStateNormal];
_getCheckMarkBtn.enabled = YES;
[_timer invalidate];
_timer = nil;
}
}
#pragma mark 获取验证码
- (IBAction)getCheckMarkBtnPress:(id)sender
{
[HttpManager getValidCode:@"忽略这些细节" resultBlock:^(id result, BOOL success, HttpResponseError *error) {
[self hideProgress];
if(success){
if (_timer == nil)//设置倒计时
{
_timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(daojishi) userInfo:nil repeats:YES];
}
[_getCheckMarkBtn setTitle:@"还剩60秒" forState:UIControlStateNormal];
_getCheckMarkBtn.enabled = NO;
}
}];
}
//进入后台
- (void)realStateInBackground
{
NSTimeInterval time = [[NSDate date] timeIntervalSince1970];
_backTime = (long long int)time;
NSLog(@"进入后台:%lld", _backTime);
}
//进入前台
- (void)realStateInForeground
{
NSTimeInterval time = [[NSDate date] timeIntervalSince1970];
_forgTime = (long long int)time;
NSLog(@"进入前台:%lld", _forgTime);
//时间差
long long int timeCha = _forgTime - _backTime;
_timeNum = _timeNum - timeCha;
}
- (void)dealloc
{
[Tools NSLogClassDestroy:self];
}
@end
需要特别注意的是这里使用的是NSTimer,如果想要控制器在pop的时候释放资源的话,必须将其设置为nil,否者将无法释放资源。当然这里完全也可以用GCD来实现