NSTimer+UIScrollView

  • 在此备注一下RunLoop的知识

  • RunLoop的运行模式(CFRunLoopModeRef)

  • 一个 RunLoop包含若干个Mode,每个Mode又包含若干个Source/Timer/Observer,每次RunLoop启动时,只能指定其中一个Mode,这个Mode被称作 CurrentMode如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入。

  • 系统默认模式

  • 1 NSDefaultRunLoopMode:App的默认Mode,通常主线程是在这个Mode下运行
  • 2 UITrackingRunLoopMode:界面跟踪Mode,用于ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
  • 3 UIInitializationRunLoopMode:在刚启动App时第进入的第一个 Mode,启动完成后就不再使用
  • 4 GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
  • 5 NSRunLoopCommonModes:这是一个占位用的Mode,不是一种真正的Mode
1
2
3
4
5
6
// 新建NSTimer对象
self.testTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(testTimerlog) userInfo:nil repeats:YES];

// 将NSTimer添加到RunLoop中,并且告诉系统,当前Tiemr只有在RunLoop的默认模式下才有效
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
// 所以在UITrackingRunLoopMode模式下,定时器的方法不会执行,但定时器仍计时
  • 将NSTimer添加到RunLoop中,并且告诉系统,当前Tiemr只有在Tracking的默认模式下才有效
1
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
  • 将NSTimer添加到RunLoop中,并且告诉系统,在所有被”标记”common的模式都可以运行,UITrackingRunLoopMode和kCFRunLoopDefaultMode都被标记为了common模式,所以只需要将timer的模式设置为forMode:NSRunLoopCommonModes,就可以在默认模式和追踪模式都能够运行
1
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
  • 如果是通过scheduledTimerWithTimeInterval创建的NSTimer, 默认就会添加到RunLoop得DefaultMode中 , 所以它会自动运行
1
2
3
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(show) userInfo:nil repeats:YES];
// 虽然默认已经添加到DefaultMode中,但是我们也可以自己修改它的模式
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];