• iOS消息循环-模式匹配


    以下内容均来自互联网,但属于个人摘录总结,主要分析一下“只有当消息循环的模式与事件模式匹配时,消息循环才会运行”这句话的模式匹配,是哪些模式匹配哪些模式。

    每个线程都有一个消息循环,主线程消息循环默认开启,子线程消息循环默认都是关闭的,需要手动开启。消息循环与线程之间是一一对应的关系,其关系保存在一个全局字典里面(字典的key为线程,value为消息循环)。

    你只能在线程结束时销毁消息循环。除了主线程即UI线程,你只能在线程内部获取消息循环。

    为消息循环添加事件,事件有两种类型:

    • 输入源:异步传递事件,通常是来自不同的线程或不同的应用的消息。输入源异步传递事件到对应的处理程序和在线程关联的NSRunLoop对象调起runUntilDate:方法来退出事件处理。
    • 定时源:同步地传递事件,发生在每个定时器调用或周期性地调用。Timer源传递事件到他们的处理程序,但是不会调用run loop来退出处理。
     1 - (void)viewDidLoad {
     2 
     3     [super viewDidLoad];
     4 
     5     // Do any additional setup after loading the view, typically from a nib.
     6 
     7     [self demo];
     8 
     9  
    10 
    11 }
    12 
    13 -(void) demo{
    14 
    15     NSTimer* timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(task) userInfo:nil repeats:YES];//创建定时源 指定定时源执行的方法
    16 
    17     [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    18 
    19                                                                      //将该定时源加入到当前线程下的消息循环中,指定消息循环模式为NSRunLoopCommanModes
    20 
    21 }
    22 
    23 -(void) task{
    24 
    25     NSLog(@"%@",[[NSRunLoop currentRunLoop] currentMode]);  //输出当前消息循环的模式
    26 
    27     NSLog(@"我是输入事件的定时源指定的执行方法");
    28 
    29 }

    注意上面代码中,[[NSRunLoop currentRunLoop] currentMode]是指当前消息循环的模式,而消息循环模式是输入源和定时源的一个集合,这个集合会被监听.

    每次启动运行循环,可以指定一个特殊的模式,在运行循环执行期间,只有跟特定的模式相关联的事件源才会被监听以及允许传递它们的事件,跟其它模式相关联的事件源将不会被监听。

    与其它模式想关联的源,直到随后在合适的模式通过循环后,都会接收到新的事件(比如,将timer加入run loop default模式下,当滚动时,timer不会收到回调,直到停止滚动回到default模式下)。

     上述代码执行结果

    我在故事板中添加了一个textView,上述代码中指定的消息循环模式为NSRunLoopCommanModes。拖动textView时消息循环模式为UITrackingRunLoopMode,松开后为KCFRunLoopDefaultMode,事件发生改变,对应消息循环模式也发生了改变。

    iOS消息循环的两个对象是NSRunLoop和CFRunLoop,前者是对后者的封装。

    CFRunLoop是Core Foundation框架里的对象,提供了纯c API,所有API是线程安全的。

    NSRunLoop是Cocoa框架里的对象,是对CFRunLoop的封装,API不是线程安全的。

    以下是系统定义的几种消息循环模式

    ModeNameDescription
    Default

    NSDefaultRunLoopMode(Cocoa)          

    kCFRunLoopDefaultMode (Core Foundation)

    可以用于大多数操作。在大多数时间,应该使用这种模式来启动和设置输入源。

    Connection NSConnectionReplyMode(Cocoa) Cocoa使用这种模式联合NSConnection对象来监听响应。我们很少会自己用到这种模式
    Modal NSModalPanelRunLoopMode(Cocoa) Cocoa使用这种模式来识别为模态面板准备的事件。
    Event tracking NSEventTrackingRunLoopMode(Cocoa)  Cocoa使用这种模式来约束鼠标拖拽或其它用户界面追踪循环的事件。
    Common modes

    NSRunLoopCommonModes(Cocoa)

    kCFRunLoopCommonModes (Core Foundation)

    公共模式,在任何模式下都可以接收。使用这种模式关联输入源,同样会关联这个模式组里面的每一种模式。

    Core Foundation初始状态下只包含 default 模式,但是可以通过 CFRunLoopAddCommonMode函数来添加自定义模式。

    模式目的普通模式的一部分?
    kCFRunLoopDefaultMode 默认的运行循环模式,几乎涵盖所有的来源。 你应该总是添加源和计时器这种模式下,如果没有特别的原因。 可以用符号kCFRunLoopDefaultModeNSDefaultRunLoopMode进行访问。
    NSTaskDeathCheckMode 通过使用NSTask来检查任务仍在运行。
    _kCFHostBlockingMode 
    _kCFNetServiceMonitorBlockingMode 
    _kCFNetServiceBrowserBlockingMode 
    _kCFNetServiceBlockingMode 
    _kCFStreamSocketReadPrivateMode 
    _kCFStreamSocketCanReadPrivateMode 
    _kCFStreamSocketWritePrivateMode 
    _kCFStreamSocketCanWritePrivateMode 
    _kCFStreamSocketSecurityClosePrivateMode 
    _kCFStreamSocketBogusPrivateMode 
    _kCFURLConnectionPrivateRunLoopMode 
    _kProxySupportLoadingPacPrivateMode 
    _kProxySupportSyncPACExecutionRunLoopMode
    _kCFStreamSocketSecurityClosePrivateMode
    使用各种私人运行的循环模式CFNetwork的阻止操作 没有
    UITrackingRunLoopMode UI跟踪。
    GSEventReceiveRunLoopMode 接收系统事件。 没有
    com.apple.securityd.runloop 与securityd通信。 通过使用跳板而已。 没有
    FigPlayerBlockingRunLoopMode QuickTime的关系。 没有

      

  • 相关阅读:
    筛法“四不像”——《C解毒》试读
    五花八门的main()
    新编《守株待兔》—C语言版—兼聊为什么不应该用%d格式转换输出指针
    含糊之过、多做之过及乱做之过
    怎样调戏程序
    混乱是怎样炼成的——《C解毒》试读
    到处忙活与一劳永逸
    “函数声明”、“函数原型”与“函数定义”辨析
    关于函数原型的对话
    内裤外穿——错位及不伦不类
  • 原文地址:https://www.cnblogs.com/xiaokaka/p/5563414.html
Copyright © 2020-2023  润新知