个人博客地址 NSTimer误差原因 (NSDefaultRunLoopMode 是普通状态下,TrackingRunLoopMode是处于滑动状态)
1,NSTimer添加在主线程中,模式是NSDefaultRunLoopMode, 主线程处理所有添加在主线程中的事件,例如UI界面的刷新,复杂的运算,等等,过多主线程事件的处理,导致线程阻塞。
2,模式的改变,当NSTimer添加到NSDefaultRunLoopMode中的时候,会重复调用,当滑动ScrollView的时候,Runlop会将Model切换到TrackingRunLoopMode,这时候的NSTimer事件就不会回调,所以不准。
<!more->
@interface ViewController ()
/**
定时器1
*/
@property (nonatomic,strong)NSTimer *timer;
@end
- (void)viewDidLoad {
[super viewDidLoad];
// 主线程
[self mainThreadTimerOne];
[self mainThreadTimerTwo];
// 子线程
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(childThreadThree) object:nil];
[thread start];
}
主线程中NSTimer
#pragma mark - 主线程创建定时器
/*
@NSTimeInterval 设置时间间隔
@target 发送的对象
@selector 调用一个实例方法
@userInfo 用于向selector方法中传参数,
@repeats 是否重复
*/
- (void)mainThreadTimerOne
{
_timer = [NSTimer timerWithTimeInterval:9 target:self selector:@selector(changerViewColor:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
}
- (void)mainThreadTimerTwo
{
_timer = [NSTimer scheduledTimerWithTimeInterval:9 target:self selector:@selector(changerViewColor:) userInfo:nil repeats:YES];
[_timer fire];// 立即执行
}
子线程中的定时器
注意: 1, 子线程RunLoop默认关闭,需手动开启 2, 子线程定时器结束的时候,需要干掉,否则会造成资源的浪费
#pragma mark - 子线程创建定时器
- (void)childThreadThree
{
_timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(changerViewColor:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
// 终止NSTimer
[self performSelector:@selector(timeInterval) withObject:nil afterDelay:5];
}
#pragma mark - 响应事件
- (void)changerViewColor:(NSTimer *)sender
{
self.view.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1.0];
}
#pragma mark - 定时器释放
- (void)timerInvalidate
{
[_timer invalidate];
_timer = nil;
}
解决方案
将NSTimer实例加到main runloop的特定NSRunLoopCommonModes(模式)中。避免被复杂运算操作或者UI界面刷新所干扰。
[[NSRunLoop currentRunLoop] addTimer:timer1 forMode:NSRunLoopCommonModes];
来源:oschina
链接:https://my.oschina.net/u/2731282/blog/1823011