iOS-RunLoop

现在对iOS开发者要求越来越高,RunLoop其实在开发中很少会用到但是也需要我们去了解。

RunLoop简单介绍

RunLoop其实就是一个简单的运行循环,保持程序的持续运行,处理App各种事件(比如触摸事件,定时事件,Selector事件),RunLoop的一个特性是该做事的时候做事,该休息的时候休息。这样可以节省CPU资源,提高程序性能。


RunLoop处理逻辑.png

RunLoop的类

  • CFRunLoopRef
  • CFRunLoopModeRef
    • NSDefaultRunLoopMode :默认模式(当界面有拖动的时候,不会执行加入此RunLoop里面方法)
    • UITrackingRunLoopMode: 界面追踪模式(当界面有拖动的时候,执行其中方法)
    • NSRunLoopCommonModes:NSDefaultRunLoopMode + UITrackingRunLoopMode(不管是否拖动都会执行其中方法)
  • CFRunLoopSourceRef
    • Source0:非基于Port的(用户调用的事件)
    • Source1:基于Port的(系统调用的事件)
  • CFRunLoopTimerRef
  • CFRunLoopOBserverRef


    RunLoop结构.png

    每个RunLoop都有需要一个自己的运行模式(Model),每个模式里面至少有一个Source或Timer,也可以添加Observer。

RunLoop对象

iOS有2套API来访问RunLoop:

  • NSRunLoop
    这个是基于CFRunLoopRef的一层OC包装。
    //1.获得主线程对应的runloop
    NSRunLoop *mainRunLoop = [NSRunLoop mainRunLoop];
    //2.获得当前线程对应的runLoop
    NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
    
  • CFRunLoopRef
    //1.获得主线程对应的runloop
    CFRunLoopGetMain()
    //2.获得当前线程对应的runLoop
    CFRunLoopGetCurrent()
    

RunLoop与线程

RunLoop和线程是一一对应的,主线程的runloop已经默认是开启的,但是子线程的需要手动开启。

//获取runloop
NSRunLoop *currentRunloop = [NSRunLoop currentRunLoop];
//开启runloop
[currentRunloop run];//这里开启的条件是需要给RunLoop添加一个Source或Timer。

RunLoop的观察者

添加观察者能够监控RunLoop状态的改变

//1.创建监听者
    /*
     第一个参数:怎么分配存储空间
     第二个参数:要监听的状态 kCFRunLoopAllActivities 所有的状态
     第三个参数:时候持续监听
     第四个参数:优先级 总是传0
     第五个参数:当状态改变时候的回调
     */
 CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
        //activity表示不同的状态
         kCFRunLoopEntry =  即将进入runloop
         kCFRunLoopBeforeTimers = 即将处理timer事件
         kCFRunLoopBeforeSources = 即将处理source事件
         kCFRunLoopBeforeWaiting = 即将进入睡眠
         kCFRunLoopAfterWaiting = 被唤醒
         kCFRunLoopExit = runloop退出
         kCFRunLoopAllActivities 
 });
//添加观察者
/*
 第一个参数:要监听哪个runloop
 第二个参数:观察者
 第三个参数:运行模式
 */
CFRunLoopAddObserver(CFRunLoopGetCurrent(),observer, kCFRunLoopDefaultMode);

RunLoop的应用场景

  • 定时器
    //1.创建定时器
    NSTimer *timer =  [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    //2.添加定时器到runLoop中,指定runloop的运行模式为
    /*
       第一个参数:定时器
       第二个参数:runloop的运行模式
       NSDefaultRunLoopMode:默认(当界面有拖动的时候,不会执行其方法)
       UITrackingRunLoopMode:界面追踪(当界面拖动的时候执行其中方法)
       NSRunLoopCommonModes:NSDefaultRunLoopMode + UITrackingRunLoopMode(不管是否拖动都会执行其方法)
    */
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    
  • 定时器第二种用法
    //该方法内部自动添加到runloop中,并且设置运行模式为默认
    [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    
  • 常驻线程
    场景是当我们需要一个一直运行的子线程来做一些事情的时候。
    //1.创建线程
    self.thread = [[NSThread alloc]initWithTarget:self selector:@selector(task1) object:nil];
    [self.thread start];
    //2.在线程方法让子线程的RunLoop跑起来
    -(void)task1
    {
      //1.获得子线程对应的runloop
      NSRunLoop *runloop = [NSRunLoop currentRunLoop];
      //2.需要给runloop添加一个源保证其不退出
      [runloop addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
      //3.开启runloop
      [runloop run];
    }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容

  • Run loop 剖析:Runloop 接收的输入事件来自两种不同的源:输入源(intput source)和定时...
    Mitchell阅读 12,426评论 17 111
  • 1.基本作用(作用重大) a 保持程序的持续运行(ios程序为什么能一直活着不会死)b 处理app中的各种事件(比...
    BEYOND黄阅读 216评论 0 3
  • 先贴下 apple doc, 本文基本是对照 doc 的翻译:https://developer.apple.co...
    brownfeng阅读 6,855评论 8 111
  • Runloop是iOS和OSX开发中非常基础的一个概念,从概念开始学习。 RunLoop的概念 -般说,一个线程一...
    小猫仔阅读 991评论 0 1
  • iOS RunLoop进阶 上一篇文章<从安卓的Looper到iOS RunLoop>谈论了安卓的Message,...
    践行者阅读 3,393评论 4 35