美文网首页程序员
滑动时的NSTimer

滑动时的NSTimer

作者: 逾期的誓言 | 来源:发表于2018-05-09 20:32 被阅读24次

个人博客地址
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];

相关文章

网友评论

    本文标题:滑动时的NSTimer

    本文链接:https://www.haomeiwen.com/subject/xniorftx.html