• NSRunloop简介



    1. NSRunLoop是IOS消息机制的处理模式
    • NSRunLoop的主要作用:控制NSRunLoop里面线程的执行和休眠,在有事情做的时候使当前NSRunLoop控制的线程工作,没有事情做让当前NSRunLoop的控制的线程休眠。

    • NSRunLoop 就是一直在循环检测,从线程start到线程end,检测inputsource(如点击,双击等操作)同步事件,检测timesource同步事件,检测到输入源会执行处理函数,首先会产生通知,corefunction向线程添加runloop observers来监听事件,意在监听事件发生时来做处理。

    介绍:

    NSRunloop类用来处理类似键盘鼠标之类的输入源,NSPort对象或者NSConnection对象。同时也可以处理NSTimer对象。

    不能创建和显示管理NSRunloop对象。主线程内的NSThread都已经自动创建了NSRunloop对象。

    通过 [NSRunloop currentRunLoop] 获得当前线程的NSRunloop对象。
    

    NSTimer对象使用 fire 方法时不会创建NSRunloop对象。
    NSTimer当使用scheduled 初始化时会把timer以默认模式添加到当前NSRunloop中,而当使用timer方法初始化时,需要自己手动将timer添加到NSRunloop中。

    [[NSRunLoop currentRunLoop]addTimer:myTimer forMode:NSDefaultRunLoopMode];
    
    如果不启动run loop,timer的事件是不会响应的
    

    NSRunloop不是线程安全的。

    runloop和线程有什么关系

    Run loops是线程的基础架构部分, Cocoa 和 CoreFundation 都提供了 run loop 对象方便配置和管理线程的 run loop (以下都以 Cocoa 为例)。每个线程,包括程序的主线程( main thread )都有与之相应的 run loop 对象。

    runloop 和线程的关系:

    1. 主线程的run loop默认是启动的。

      iOS的应用程序里面,程序启动后会有一个如下的main()函数

       int main(int argc, char * argv[]) {
       @autoreleasepool {
       	return UIApplicationMain(argc, argv, nil, 			NSStringFromClass([AppDelegate class]));
       }
       }
      

      重点是UIApplicationMain()函数,这个方法会为main thread设置一个NSRunLoop对象,这就解释了:为什么我们的应用可以在无人操作的时候休息,需要让它干活的时候又能立马响应。

    2. 对其它线程来说,run loop默认是没有启动的,如果你需要更多的线程交互则可以手动配置和启动,如果线程只是去执行一个长时间的已确定的任务则不需要。

    3. 在任何一个 Cocoa 程序的线程中,都可以通过以下代码来获取到当前线程的 run loop 。

       NSRunLoop *runloop = [NSRunLoop currentRunLoop];
      

    参考链接:《Objective-C之run loop详解》

    runloop的mode作用是什么?

    model 主要是用来指定事件在运行循环中的优先级的,分为:

    • NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
    • UITrackingRunLoopMode:ScrollView滑动时
    • UIInitializationRunLoopMode:启动时
    • NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合

    苹果公开提供的 Mode 有两个:

    • NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
    • NSRunLoopCommonModes(kCFRunLoopCommonModes)

    以+ scheduledTimerWithTimeInterval...的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?

    RunLoop只能运行在一种mode下,如果要换mode,当前的loop也需要停下重启成新的。利用这个机制,ScrollView滚动过程中NSDefaultRunLoopMode(kCFRunLoopDefaultMode)的mode会切换到UITrackingRunLoopMode来保证ScrollView的流畅滑动:只能在NSDefaultRunLoopMode模式下处理的事件会影响ScrollView的滑动。

    如果我们把一个NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主运行循环中的时候, ScrollView滚动过程中会因为mode的切换,而导致NSTimer将不再被调度。

    同时因为mode还是可定制的,所以:

    Timer计时会被scrollView的滑动影响的问题可以通过将timer添加到NSRunLoopCommonModes(kCFRunLoopCommonModes)来解决。代码如下:

    //将timer添加到NSDefaultRunLoopMode中
    [NSTimer scheduledTimerWithTimeInterval:1.0
     target:self
     selector:@selector(timerTick:)
     userInfo:nil
     repeats:YES];
    //然后再添加到NSRunLoopCommonModes里
    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0
     target:self
     selector:@selector(timerTick:)
     userInfo:nil
     repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];	
    

    参考链接 深入理解RunLoop

  • 相关阅读:
    Modelsim中观测代码覆盖率
    Allegro中Thermal relief Pad 和Anti Pad
    时序逻辑中阻塞赋值引起的仿真问题
    如何提高FPGA工作频率(转载)
    `include在Verilog中的应用
    forever
    wxpython 应用 使用 google gauth 认证
    sql to sqlalchemy 转换
    django 简易博客开发 5 markdown支持、代码高亮、gravatar头像服务
    simpletodo: 一个简易的 todo 程序 django版
  • 原文地址:https://www.cnblogs.com/sunyanyan/p/5242835.html
Copyright © 2020-2023  润新知