NSTimer 两种常用创建方式的区别

原创 2015年11月21日 18:33:41

NSTimer 有两种常用创建方式。

//第一种,使用 timerWithTimeInterval:target:selector:userInfo:repeats: 方法
timer = [NSTimer timerWithTimeInterval:1
                                target:singleTimerManager
                              selector:@selector(timerRepeat:)
                              userInfo:nil repeats:YES];

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


//第二种,使用 scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: 方法
timer = [NSTimer scheduledTimerWithTimeInterval:1.
                                         target:singleTimerManager
                                       selector:@selector(timerRepeat:)
                                       userInfo:nil
                                        repeats:YES];

由于第二种scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: 方法是比第一种要少一行的,所以一般我会使用第二种,但今天发现,在 scrollview 加入一个 lable,lable 显示倒计时时间,那么在滑动 scrollview 时,倒计时会停止,scrollview 滑动完成以后,倒计时才会继续进行。

换成timerWithTimeInterval:target:selector:userInfo:repeats:方法以后,在滑动 scrollview 时,倒计时仍会进行,不会停止。

这两个方法的入参没什么不同,那么关键一定在[[NSRunLoop currentRunLoop] addTimer:timer
forMode:NSRunLoopCommonModes];这行,跳转 NSRunLoopCommonModes 的定义,发现还有一个 NSDefaultRunLoopMode。

FOUNDATION_EXPORT NSString * const NSDefaultRunLoopMode;
FOUNDATION_EXPORT NSString * const NSRunLoopCommonModes NS_AVAILABLE(10_5, 2_0);

将第一种方式中的 NSRunLoopCommonModes 改为 NSDefaultRunLoopMode,运行,发现效果就与第二种方式相同了。推断第二种方式是默认使用 NSDefaultRunLoopMode。

但是 NSRunLoopCommonModes 和 NSDefaultRunLoopMode 是干什么用的呢?查资料得:

  1. NSDefaultRunLoopMode:默认的运行模式,用于大部分操作,除了NSConnection对象事件。
  2. NSConnectionReplyMode:用来监控NSConnection对象的回复的,很少能够用到。
  3. NSModalPanelRunLoopMode:用于标明和Mode Panel相关的事件。
  4. NSEventTrackingRunLoopMode:用于跟踪触摸事件触发的模式(例如UIScrollView上下滚动)。
  5. NSRunLoopCommonModes:是一个模式集合,当绑定一个事件源到这个模式集合的时候就相当于绑定到了集合内的每一个模式。

Cocoa应用默认包含Default、Panel、Event Tracking模式,Core Foundation只包含Default模式,我们可以通过CFRunLoopAddCommonMode添加模式。

这一段我没怎么看懂,又发现了一篇文章,里面写到:

NSDefaultRunLoopModel:监听用户最基本的操作(点击,触摸等)
NSRunLoopCommonModels:监听一些特殊操作:滚动等

那么,为什么在NSDefaultRunLoopModel模式下发生滚动,计时器会停止呢?那是因为系统认为,用户不应该边滚动边操作界面,所以停止了(触碰,点击等)NSDefaultRunLoopModel模式下监听的事件。

有点儿明白了,继续查资料,在介绍 RunLoop 的文里写到:

主线程的 RunLoop 里有两个预置的 Mode:kCFRunLoopDefaultMode 和 UITrackingRunLoopMode。这两个 Mode 都已经被标记为”Common”属性。DefaultMode 是 App 平时所处的状态,TrackingRunLoopMode 是追踪 ScrollView 滑动时的状态。当你创建一个 Timer 并加到 DefaultMode 时,Timer 会得到重复回调,但此时滑动一个TableView时,RunLoop 会将 mode 切换为 TrackingRunLoopMode,这时 Timer 就不会被回调,并且也不会影响到滑动操作。

再尝试一下,改为

timer = [NSTimer timerWithTimeInterval:1 target:singleTimerManager selector:@selector(timerRepeat:) userInfo:nil repeats:YES];

//#import <UIKit/UIApplication.h>
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];

则只 timer 会在 scrollview 滑动时调用 timerRepeat: 方法。

版权声明:本文为博主原创文章,未经博主允许不得转载。

在寻找NSRunLoopCommonModes和NSDefaultRunLoopMode区别时发现

当实例化NSTimer对象的时候,通常会使用 scheduledTimerWithTimeInterval 方法。该方法会自动为我们实例化的timer添加到当前线程的RunLoop中,并且默认模式是 ...
  • sinat_29626041
  • sinat_29626041
  • 2016年10月09日 12:06
  • 1604

IOS下的 NSTimer与Run loop Modes

一.NSRunLoop 在Cocoa中,每个线程(NSThread)对象中内部都有一个run loop(NSRunLoop)对象用来循环处理输入事件,处理的事件包括两类,一是来自Input so...
  • yuquan0821
  • yuquan0821
  • 2013年11月20日 13:51
  • 12786

NSTimer的使用以及 史上最简单的,NSTimer暂停和继续

NSTimer的使用方法 1、初始化 + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget select...
  • samuelltk
  • samuelltk
  • 2012年04月21日 16:16
  • 89748

NSTimer 详解

NSTimer的使用方法 1、初始化 + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector...
  • HDFQQ188816190
  • HDFQQ188816190
  • 2016年10月10日 16:56
  • 1654

NSTimer和实现弱引用的timer的方式

NSTimer 弱引用 Objective-C
  • yohunl
  • yohunl
  • 2016年01月31日 22:44
  • 5542

NSTimer

看到这个标题,你可能会想NSTimer不就是计时器吗,谁不会用,不就是一个能够定时的完成任务的东西吗?   我想说你知道NSTimer会retain你添加调用方法的对象吗?你知道NS...
  • yongyinmg
  • yongyinmg
  • 2014年03月03日 16:54
  • 1217

NSTimer

NSTimer fire 我们先用 NSTimer 来做个简单的计时器,每隔5秒钟在控制台输出 Fire 。比较想当然的做法是这样的: 1 2 3 4 5 6 7 8 ...
  • u011010305
  • u011010305
  • 2016年09月18日 13:23
  • 259

[NSTimer]NSTimer你真的会用了吗

看到这个标题,你可能会想NSTimer不就是计时器吗,谁不会用,不就是一个能够定时的完成任务的东西吗?   我想说你知道NSTimer会retain你添加调用方法的对象吗?你知道NSTimer是...
  • Jeff_NJUT
  • Jeff_NJUT
  • 2014年11月26日 16:47
  • 529

NSTimer定时器进阶——详细介绍,循环引用分析与解决

引言 定时器:A timer waits until a certain time interval has elapsed and then fires, sending a specifie...
  • ailongyang
  • ailongyang
  • 2017年03月10日 11:07
  • 1089

NSTimer的使用以及NSTimer暂停和继续

NSTimer的使用方法 1、初始化 + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget select...
  • jianandjan
  • jianandjan
  • 2016年01月02日 16:19
  • 508
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:NSTimer 两种常用创建方式的区别
举报原因:
原因补充:

(最多只允许输入30个字)