Run Loop

link 死循环

Why we need this

  • 保持程序持续运行
  • 处理各种事件(触摸,定时器,Selector)
  • 节省CPU,提高性能(该做事做事,该休息休息)
  • 如果没有run loop 程序会立刻退出
    int main(int argh, char* argv[] {
    @autoreleasepool {
      return UIApplicationMain(argh, argue, nil, NSStringFromClass([AppDelegate class]));  
    }
    }
    

OC: NSRunLoop C: CFRunLoop (coreFundation)

RunLoop && Thread

  • 每条线程都有位移一个Runloop对象一一对应, 主线程自动创建,子线程要手动创建,结束时销毁
  • 内部实现,传入线程参数,如果不在字典里,则创建(懒加载)。用字典存线程和runloop对象,
//获取runloop对象 
[NSRunLoop mainLoop]; 
[NSRunLoop currentRunLoop];

RunLoop Mode

  • Runloop中可能存在一个或多个Mode, 但启动后只能选择一种Mode。
  • Mode里面至少有一个timer或source.
  • Mode种类:default, Tracking, Common(占位用的,支持前两种)/Source/Observe
//获得mode
[NSRunLoop currentRunLoop].currentMode

添加定时器到RunLoop,并指定mode。

NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 xxx:@selector xxRepeated:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultMode];

ISSUE 两个scroll 滚动一个另一个不工作

原因是: scroll的时候会切换到tracking模式。导致其他模式不工作。可切换上面的defaultmode为trackingmode,那么只有scroll的时候才工作。要想任何时候都工作,要改为commonMode。 定时器schedule与timerWithTimeInterval不同,schedule会自动加入到runloop中并且设置mode为default.

[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(xx) repeats:YES];

如果在子线程开启上面的timer,不会执行。因为没有runloop(子线程runloop要手动创建),也要手动开启。

- (void) run {
  NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
  [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(xx) repeats:YES];
  [currentRunloop run];
}

GCD定时器

  • dispatch source。 不受RunLoop任何模式影响

RunLoop的执行

Runloop应用

  • NSTimer
  • ImageView 显示GIF
  • PerformSelector
  • 常驻线程
  • @autoreleasepool { }

results matching ""

    No results matching ""