`
lizaochengwen
  • 浏览: 644528 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

线程 NSRunLoop概念3

阅读更多
转自:http://blog.csdn.net/lingedeng/article/details/6868734

Run loop mode是一组用于监控的input sources和timers以及一组用于通知的run loop observers。每次运行一个run loop,你指定(显式或隐式)run loop的运行模式。当相应的模式传递给run loop时,只有与该模式对应的input sources才被监控并允许run loop对事件进行处理(与此类似,也只有与该模式对应的observers才会被通知)。与指定模式不同的事件将被事件源保存下来直到相关的模式被注册后才被分发。

        在你的代码中,mode使用名称来标识。在Cocoa和Core Foundation都定义了缺省模式和几个通用模式,使用字符串来对它们进行标识。你可以通过使用自定义的字符串来自定义模式。虽然可以为自定义的模式指定任意的名字,但模式所包含的内容却是固定的。也就是你必须为你自定义的模式添加一个或多个input sources,Timers或run-loop observers供模式使用。

        你使用mode来对unwanted sources中通过run loop传递的事件进行过滤。大多数情况下,你希望你的run loop运行在系统定义的缺省模式下。A modal panel, however, might run in the “modal” mode. While in this mode, only sources relevant to the modal panel would deliver events to the thread. For secondary threads, you might use custom modes to prevent low-priority sources from delivering events during time-critical operations.

        注:mode只对事件源进行区分,而不是事件类型。例如:你不能使用mode来匹配光标按键事件或键盘事件。你可以使用mode来监听一组不同的端口,使timer临时挂起或者改变当前监控的sources或run-loop observers。

        下表为Cocoa和Core Foundation中定义的模式及简要描述。name列中是你在代码中指定的mode常量:
--------------------------------------------------------------------------------
Mode     Name Description
--------------------------------------------------------------------------------
default    NSDefaultRunLoopMode(Cocoa)
           kCFRunLoopDefaultMode(Core Foundation) default mode是大多数操作中使用的模式。大多数时间,你使用该模式来启动run loop并配置你的input sources。
--------------------------------------------------------------------------------
connection NSConnectionReplyMode(Cocoa) Cocoa使用该模式与NSConnection对象联接用于监控响应。你通常不需要在你的代码中使用该模式。
--------------------------------------------------------------------------------
modal    NSModalPanelRunLoopMode(Cocoa) Cocoa使用该模式来标识用于modal panel(模式面板)的事件。
--------------------------------------------------------------------------------
event tracking NSEventTracking-RunLoopMode (Cocoa) Cocoa使用该模式来限制光标拖动循环中上报的事件或其它用户界面相关的trace loop。
--------------------------------------------------------------------------------
common modes NSRunLoopCommonModes(Cocoa)
                kCFRunLoopCommonModes(Core Foundation) 这是一组可配置的通用模式。将input sources与该模式关联则同时也将input sources与该组中的其它模式进行了关联。对于Cocoa应用,该模式缺省的包含了default,modal以及event tracking模式。而Core Foundation则在初始化时只包含了default模式。你可以使用CFRunLoopAddCommonMode为该模式添加自定义的模式。
--------------------------------------------------------------------------------
Input sources

        input sources将事件以异步的形式发送给你的thread。事件源依赖于input sources的类型,通常分成一或两组。基于端口的事件源监控你机器的端口,自定义输入源监控事件的自定义源。Run loop并不关心input sources是基于端口或自定义的事件源。两个不同的输入源唯一的区别就是它们的标识方式。基于端口的输入源标识由内核自动生成,自定义的输入源由另外的thread手动产生。

       当你创建了一个input sources,将其指定给你的run loop并分配一个或多个mode。当mode分配时会对input source的监控产生即时的影响。大多数情况,你运行你的run loop在缺省模式下,同时你也可以指定自定义模式。如果一个input sources不在当前监控的模式中,任何由该sources产生的事件都将被保存直至run loop运行于相应的模式下。
  Port-Based sources

        Cocoa和Core Foundation内置提供使用port相关的对象和函数创建port-based sources。例如,在Cocoa中你从来就不需要直接创建input sources。你只需要使用port对象以及NSPort的方法将port添加到run loop。Port对象将为你创建和配置input sources。

        在Core Foundation,你需要自己创建port和run loop输入源。此时,你将使用与port不透明类型相关的函数(CFMachPortRef, CFMessagePortRef,CFSocketRef)来创建合适的对象。
  自定义输入源

        要创建自定义输入源,你必须使用与CFRunLoopSourceRef不透明类型相关的函数。你将使用数个回调函数来配置自定义输入源。Core Foundation通过在不同的时间来调用这些回调函数以完成source配置,处理事件以及当该source从run loop中移除时关闭该source。

        除了定义当有事件到达时自定义输入源的行为,你还必须定义事件投递机制。This part of the source runs on a separate thread and is responsible for providing the input source with its data and for signaling it when that data is ready for processing. The event delivery mechanism is up to you but need not be overly complex.
  Cocoa perform selector source

        除了port-based sources,Cocoa定义了一组自定义输入源用于在任何thread中执行一个方法(selector)。与port-based源相类似,perform selector在thread中被序列化执行,这样就缓和了许多在同一个thread中运行多个方法所产生的同步问题。与port-based sources不同的是,perform selector source在运行完selector后自动从run loop中移除。

        当在非main thread中perform selector时,其thread中必须有一个激活的run loop。对于你自己创建的thread而言,只有你的代码显式的运行一个run loop后该perform selector才能得到执行。Run loop在当loop运行时处理所有已排队的perform selector,而不是在一个loop循环时只处理某一个perform selector。

       下表展示了perform selector调用方法:
--------------------------------------------------------------------------------
Methods Description
--------------------------------------------------------------------------------
performSelectorOnMainThread: withObject: waitUntilDone:
performSelectorOnMainThread: withObject: waitUntilDone:modes: 在应用程序的main thread的下一个run loop周期内调用指定的selector。这些方法为你提供了堵塞当前thread执行直至selector执行完成。
--------------------------------------------------------------------------------
performSelector: onThread:withObject: waitUntilDone:
performSelector: onThread:withObject: waitUntilDone:modes: 在已有的thread中调用指定的selector。这些方法为你提供了堵塞当前thread执行直至selector执行完成。
--------------------------------------------------------------------------------
performSelector: withObject: afterDelay:
performSelector: withObject: afterDelay:inModes: 在当前的thread的下一个run loop周期内并延迟一个可选的时间,调用指定的selector。
--------------------------------------------------------------------------------
cancelPreviousPerformRequestsWithTarget:
cancelPreviousPerformRequestsWithTarget: selector:object: 用于取消使用第三行中方法发向thread的消息。
--------------------------------------------------------------------------------
什么时候使用run loop?

        只有在你创建了第二个thread时你才需要显式的运行run loop。对于main thread的run loop是作为框架的一部分。所以Cocoa和Carbon框架提供自动运行应用程序主循环的代码。IOS中UIApplication的run方法用于启动应用程序主循环并作为启动序列的一部分。如果你是使用Xcode template生成应用程序,则不需要对run方法进行显式的调用。

        对于第二个thread,你需要决定是否有必要使用run loop,如果需要,则需要你手工进行配置和启动。你并不需要为每个新建的thread都建立run loop。例如:如果你使用你的thread运行一些长时间运行且可预知结果的任务,你就可以不启动该thread的run loop。Run loop所要解决的问题是你需要与该thread有很多的交互。

      如遇到以下的情况,则你就需要启动thread内的run loop:

          使用ports或自定义的input sources与其它thread进行交互;

          在thread中使用Timers(定时器);

          在Cocoa应用中使用任意performSelector...方法;

          需要使用thread完成周期性的任务。

       如果你决定使用run loop,则配置和运行将很直接。就像所有的多thread编程,你将考虑你新建thread的中止条件。总是将新建的thread安全退出好过强制退出
分享到:
评论

相关推荐

    也来谈谈CFRunLoop(NSRunLoop)

    NULL 博文链接:https://modun.iteye.com/blog/1600588

    LightWeightRunLoop-A-Reactor-Style-NSRunLoop, NSRunLoop反应器样式实现.zip

    LightWeightRunLoop-A-Reactor-Style-NSRunLoop, NSRunLoop反应器样式实现 LightWeightRunLoop在其他线程,定时器,URLConnection,LWStream ( LWInputStream、LWOutputStream ),LWPort ( LWSocketPort ) 等上实现 ...

    取消同步的ASIHTTPRequest请求

    [[NSRunLoop currentRunLoop] runMode:[self runLoopMode] beforeDate:[NSDate distantFuture]]; } } 可以看到,在执行[self main]后,执行了个包含NSRunLoop的while循环,此循环应该就是在等待数据访问结束,...

    TestRunLoopDemo

    在Thread的NSRunloop中添加进RunLoopSource也是在IOS里面获取常驻线程的一个主要方法手段(开源项目AFNetworking就是用这种手段获取的常驻线程)。从该演示代码我们还可以一窥Objective-C是怎样封装C以提供更加简单...

    RunLoop例子

    RunLoop例子

    CFRunLoop源码

    NSRunLoop是基于CFRunLoopRef的封装,不是线程安全 CFRunLoopRef的线程安全性:CFRunLoopRef不是在线程刚创建的时候创建的,而是在线程获取的时候创建的,如果不主动获取线程,一直不会有。CFRunLoopRef在创建时通过...

    NSRunLoopDemo

    runloop相关的代码整理。Timer,CustomSource,DispatchSource,ConfigRunLoop,ObserverRunloop等

    iOS-GCD详解及简单使用

    线程、任务和队列的概念 异步、同步 & 并行、串行的特点 一条重要的准则 一般来说,我们使用GCD的最大目的是在新的线程中同时执行多个任务,这意味着我们需要两项条件: 能开启新的线程 任务可以同时执行

    RunLoop示例

    《NSThread 、NSRunLoop 和 Dispatch Queue》一文示例源代码

    CocoaAsyncSocket-7.1

    它异步的调用委托方法,使用NSRunLoop。委托方法包括 socket的参数,可让你在多个实例中区分 自包含在一个类中。你无需操作流或者socket,这个类帮你做了全部 支持基于IPV4和IPV6的TCP流 AsyncUdpSocket是UDP/IP ...

    cocoaasyncsocket

    它异步的调用委托方法,使用NSRunLoop。委托方法包括 socket的参数,可让你在多个实例中区分 自包含在一个类中。你无需操作流或者socket,这个类帮你做了全部 支持基于IPV4和IPV6的TCP流 AsyncUdpSocket是UDP/IP ...

    CocoaAsyncSocket

    它异步的调用委托方法,使用NSRunLoop。委托方法包括 socket的参数,可让你在多个实例中区分 自包含在一个类中。你无需操作流或者socket,这个类帮你做了全部 支持基于IPV4和IPV6的TCP流 AsyncUdpSocket是UDP/IP ...

    ios-打地鼠 小游戏.zip

    [[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSDefaultRunLoopMode]; 改为: /*每秒刷新60次的定时器*/ _time = [CADisplayLink displayLinkWithTarget:self selector:@selector(play)]; /*将...

    DispatchSourceTest.zip

    、NSRunLoop 和 Dispatch Queue> 一文示例源代码

    java版飞机大战源码-awesome-iOS:真棒-iOS

    GCD、NSOperationQueue、NSRunLoop、多线程安全、锁 RAC/MVVM Runtime iOS Animation、UIBezierPath、CAShapeLayer Swift CocoaPods LLDB 调试打包日志测试持续集成 证书推送上架 版本管理 Blog iOS代码库 XCode插件...

    百度地图开发java源码-iOS_develop_learning_routes:iOS开发学习路线

    多线程 NSThread GCD NSLock NSRecursiveLock OSSpinLock @synchronized POSIX pthread-mutex RunLoop CFRunLoop NSRunLoop 数据库 SQLite 网络 TCP UDP DNS解析 HTTP协议 NetworkExtension 网络安全 NSURLSession ...

    asyncsocket

    /** * In the event of an error, the socket is closed. * You may call "unreadData" during this call-back ...- (NSRunLoop *)onSocket:(AsyncSocket *)sock wantsRunLoopForNewSocket:(AsyncSocket *)newSocket;

    cocoa something related

    > [[NSRunLoop currentRunLoop] addPort:mainPort > forMode:NSDefaultRunLoopMode]; > > NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; > [parameters setObject:mainPort forKey:@"port...

    无限自动轮播图

    3.电影票样式的层次感;4.非当前显示view具有缩放和透明的特效 2.版本信息 Version 3.0.0: 弃用layoutSubviews,需要手动调用reloadData,方便懒加载等; 子控件支持跟随父控件进行缩放; 定时器添加到NSRunLoop,...

    ConcurrentCource

    ConcurrentCource自己对NSRunLoop,NSOperation,GCD的一些心得,代码中都有注释

Global site tag (gtag.js) - Google Analytics