美文网首页
NSTimer的用法

NSTimer的用法

作者: 凌巅 | 来源:发表于2017-02-14 19:55 被阅读561次

NSTimer的用法

初始化方法 五个

关于这五个初始化方法我们分为三大类

第一类
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

根据指定参数创建一个NSTimer定时器,但是并没有加入到RunLoop循环中,需要我们手动加入到主循环池中[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode,这是和第二类方法的主要区别

第二类
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

这两个方法同样依据指定参数创建一个定时器NSTimer,并自动加入到当前的RunLoop循环中,我们不需要手动加入,对比第一类方法

第三类
- (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(nullable id)ui repeats:(BOOL)rep

这个方法为NSTimer的指定构造方法,我们一般不经常用,供前面四个方法调用。当使用这个方法创建NSTimer实例的时候,需要我们手动加入到主循环池中[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode

方法参数

1.(NSTimeInterval)ti 定时器的触发时间间隔,如果这个参数<0或者=0,则默认为0.1毫秒
2.(NSInvocation *)invocation NSInvocation对象,构造定时器的回调对象。
3.(BOOL)yesOrNo 是否循环执行,YES循环,NO只执行一次
4.(id)aTarget 定时器回调时发送消息的执行对象,该对象执行(SEL)s方法
5.(SEL)aSelector 定时器回调时所执行的方法
6.(nullable id)userInfo 传递给定时器的参数信息
7.(NSDate *)date 定时器触发的时间

成员方法

- (void)fire;

立即触发此定时器,但并不影响之前设置的定时器时间间隔。如果定时器没有设置循环触发,那么执行此函数后,定时器被自动销毁,以后不会触发了。

- (void)invalidate;

停止定时器,并从循环池中移除这个定时器,从文档中可以看出,这是唯一的方法将定时器从循环池中移除。

成员变量
@property (copy) NSDate *fireDate;

设置定时器的启动时间,常用来管理定时器的启动和停止

//启动定时器

timer.fireDate = [NSDate distantPast];

[timer setFireDate:[NSDate distantPast]];


>//停止定时器

>```
timer.fireDate = [NSDate distantFuture];
或
[timer setFireDate:[NSDate distantFuture]];

//继续

timer.fireDate = [NSDate date];

[timer setFireDate:[NSDate date]];


@property (readonly) NSTimeInterval timeInterval;

只读属性,获取定时器调用的间隔时间

@property NSTimeInterval tolerance

设置定时器的误差范围
  

@property (readonly, getter=isValid) BOOL valid;

定时器是否有效  

@property (nullable, readonly, retain) id userInfo;

获取传入定时器的参数信息


###使用NSTimer的注意事项
#####循环引用导致的内存泄漏  
当我们创建NSTimer的时候,NSTimer会对传入的invocation、target这些参数强引用,直到调用```invalidate```方法,才释放这些对象。这就使得我们在使用NSTimer对象的时候要格外小心。  

例如,如果我们在```viewDidLoad```或者其他的方法中创建了NSTimer实例,但是我们要在```dealloc```中销毁,此时就会出现循环应用。因为,不调用```invalidate```方法,永远进不了```dealloc```方法;而不进入```dealloc```方法,则永远也不会调用```invalidate```方法。这个时候就会出现内存泄漏。  
避免这种情况的最简单的方法就是在```viewDidDisappear```或```viewWillDisappear```方法中调用```invalidate```方法
稍微麻烦一点就是自己对NSTimer进行封装.  

#####添加到RunLoop
NSTimer必须加入到RunLoop循环池中才会起作用,NSTimer其实也是一种事件(资源),如果NSTimer这种资源要起作用的话,就必须加入到RunLoop循环中。  
由前面我们可以了解到,通过初始化方法  

  • (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
  • (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
会将timer自动加入到当前的RunLoop中,<strong>如果此时所在的线程不是主线程,则需要我们手动启动当前线程的RunLoop</strong>```[[NSRunLoop currentRunLoop] run]```。  
我们可以在UITableViewCell中这样使用  
   

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(handleTimer) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] run]; //手动启动当前线程的RunLoop
})

  
  
######RunLoop模式切换    

有这么一种情况,我们在UITableview或者ScrollView中使用NSTimer的时候,当UITableview或者ScrollView滚动的时候,NSTimer停止了。  
比如使用这种方法在主线程中创建NSTimer  

self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(handleTimer) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];

我们将NSTimer添加到RunLoop的默认模式forMode:NSDefaultRunLoopMode,而当我们滚动ScrollView的时候RunLoop将会切换到UITrackingRunLoopMode,所以这个时候NSTimer就停止工作了,滚动完成之后,继续执行,这种情况我们可以这样处理:  

self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(handleTimer) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; //将NSTimer放在forMode:NSRunLoopCommonModes模式下,在任何情况下都能够正常工作


相关文章

  • NSTimer

    用法 NSTimer的用法很简单,个人最常用的是下面这个方法。 [NSTimer scheduledTimerWi...

  • 防止内存泄露的NSTimer定时器

    目录 NSTimer的基础用法 NSTimer的内存泄露 安全防侧漏的定时器 NSTimer的基础用法 创建定时器...

  • NSTimer用法

    IOS NSTimer 定时器用法总结 - 珲少 的个人空间 - 开源中国社区

  • NSTimer的用法

    NSTimer的用法 初始化方法 五个 关于这五个初始化方法我们分为三大类 第一类 根据指定参数创建一个NSTim...

  • NSRunLoopCommonModes和Timer

    今天学习别人的博客看到这个NSTimer的用法,我才知道我自己以前根本不知道,NSTimer有时候会无效。下面是原...

  • iOS-后台任务相关

    研究一波吧. 1.iOS 后台任务2.NSTimer的基础用法以及程序挂起后NSTimer仍然可以在后台运行计时3...

  • iOS准确的Timer

    前言 没有绝对准确的Timer,相对而言推荐CADisplayLink。 NSTimer 用法一: schedul...

  • iOS NSTimer的详细用法

    一、NSTimer的类方法和实例初始化方法 这三个方法直接将timer添加到了当前runloop default ...

  • iOS 中NSTimer的用法

    一、初始化方法:有五种初始化方法,分别是 1、+ (NSTimer *)timerWithTimeInterval...

  • NSTimer简单用法

    开始前咱们先知道NSTimer是用来的干嘛的。 从这里我们可以看出来,NSTimer就是我为了过一段时间想目标发送...

网友评论

      本文标题:NSTimer的用法

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