美文网首页
使用NSTimer时遇到的问题归类

使用NSTimer时遇到的问题归类

作者: 没有酱帅 | 来源:发表于2016-06-16 18:16 被阅读182次

    1. NSRunLoopCommonModes和Timer

      当使用NSTimer的scheduledTimerWithTimeInterval方法时。事实上此时Timer会被加入到当前线程的Run Loop中,且模式是默认的NSDefaultRunLoopMode。而如果当前线程就是主线程,也就是UI线程时,某些UI事件,比如UIScrollView的拖动操作,会将Run Loop切换成NSEventTrackingRunLoopMode模式,在这个过程中,默认的NSDefaultRunLoopMode模式中注册的事件是不会被执行的。也就是说,此时使用scheduledTimerWithTimeInterval添加到Run Loop中的Timer就不会执行。

      所以为了设置一个不被UI干扰的Timer,我们需要手动创建一个Timer,然后使用NSRunLoop的addTimer:forMode:方法来把Timer按照指定模式加入到Run Loop中。这里使用的模式是:NSRunLoopCommonModes,这个模式等效于NSDefaultRunLoopMode和NSEventTrackingRunLoopMode的结合。(参考Apple文档)

    参考代码:

    - (void)viewDidLoad{

    [super viewDidLoad];

    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(timer_callback)userInfo:nil repeats:YES];

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

    }

    总结:NSTimer默认使用NSDefaultRunLoopMode模式,这种模式的有限级较低,会被tableview的滑动调用的NSEventTrackingRunLoopMode模式阻碍,导致NSTimer会被等待执行。常规处理方式未[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes],把timer加入到forMode:NSRunLoopCommonModes模式下,这种模式可以和NSEventTrackingRunLoopMode同时执行

    2.NSTimer的释放 

    首先写一个错误的写法,怎么定义这是个错误呢,就是非常规写法.

    -(void)dealloc {

    [_timer invalidate];

    NSLog(@"%@ dealloc", NSStringFromClass([self class]));

    }

    timer创建

    _timer = [NSTimer scheduledTimerWithTimeInterval:3.0f

    target:self

    selector:@selector(timerFire:)

    userInfo:nil

    repeats:YES];

    把target设置为self,就是在NSRunloop里面强引用了self,也就是说如果这个timer不释放,那么当前self永远不会调用dealloc,通常做法就是在viewwilldiasppera或者 你自己写的一些释放方法里面调用.

    题外话:VC的创建是先初始化VC,再初始化VC上的view的父类,再初始化view。释放的时候顺序相反,程序调用dealloc的时候会这么写

    -(void)dealloc {

    }

    看着是个空函数,其实上执行了很多代码,它存在的意思就是告诉你,它要开始销毁了,他会先把VC上的view全部释放掉,然后再释放掉自己,这个空函数执行完的时候,self被释放完了(当前这个过程是由ARC控制)

    相关文章

      网友评论

          本文标题:使用NSTimer时遇到的问题归类

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