简介
Run loops are part of the fundamental infrastructure associated with threads. A run loop is an event processing loop that you use to schedule work and coordinate the receipt of incoming events. The purpose of a run loop is to keep your thread busy when there is work to do and put your thread to sleep when there is none.
runloop是与线程关联的基础架构。runloop是一个事件处理循环,用来安排工作以及即将接收到的事件。runloop是为了保持你的线程处于busy状态,有事情处理就活跃,没有事情处理就处于睡眠状态。
Run loop management is not entirely automatic. You must still design your thread’s code to start the run loop at appropriate times and respond to incoming events. Both Cocoa and Core Foundation provide run loop objectsto help you configure and manage your thread’s run loop. Your application does not need to create these objects explicitly; each thread, including the application’s main thread, has an associated run loop object. Only secondary threads need to run their run loop explicitly, however. The app frameworks automatically set up and run the run loop on the main thread as part of the application startup process.
runloop的管理部完全是自动的。你必须设计你的thread的代码在合适的时机开启线。cocoa和cocoa基础框架提供了runloop对象来帮助你配置和管理你线程的runloop。你的程序并不需要显示的创建这些这些对象,每个线程都包含了一个runloop对象。只有辅助线程需要显示的跑runloop。然而,作为应用程序启动过程的一部分,app框架自动创建和在主线程上跑runloop。
The following sections provide more information about run loops and how you configure them for your application. For additional information about run loop objects, see NSRunLoop Class Reference and CFRunLoop Reference.
下边部分提供了更多信息关于runloop以及如何为你的应用程序配置他们,下边是关于runloop对象的更多信息。
Anatomy of a Run Loop
runloop的运行原理
A run loop is very much like its name sounds. It is a loop your thread enters and uses to run event handlers in response to incoming events. Your code provides the control statements used to implement the actual loop portion of the run loop—in other words, your code provides the while or for loop that drives the run loop. Within your loop, you use a run loop object to "run” the event-processing code that receives events and calls the installed handlers.
runloop非常像像他的名字。它是通过线程进入,用来处理接下来需要响应事件的循环。你的代码提供了用于实现runloop的的控制语句。换句话说,你的代码提供了while或者for语句来运行runloop。在循环中,你用runloop对象来跑事件进程的代码,这些代码用来接收事件和调用已经安装的程序。
A run loop receives events from two different types of sources.Input sources deliver asynchronous events, usually messages from another thread or from a different application.Timer sources deliver synchronous events, occurring at a scheduled time or repeating interval. Both types of source use an application-specific handler routine to process the event when it arrives.
runloop接收从两种不同来源的事件。输入源用来处理异步事件,通常这些消息来源于另一个线程或其他的程序。时间源提供同步事件,发生在预定时间或者重复间隔。当事件发生时,两种源使用一种应用程序的特定处理程序来处理。
Figure 3-1shows the conceptual structure of a run loop and a variety of sources. The input sources deliver asynchronous events to the corresponding handlers and cause the runUntilDate:method (called on the thread’s associatedNSRunLoopobject) to exit. Timer sources deliver events to their handler routines but do not cause the run loop to exit.
下图显示了runloop的结构和何种源,输入源将异步事件传递传递给相应的处理程序,并且引起runUntilDate:方法终止。时间源会将时间传递给他们的处理机制,但是不退使runloop退出。
In addition to handling sources of input, run loops also generate notifications about the run loop’s behavior. Registered run-loop observers can receive these notifications and use them to do additional processing on the thread. You use Core Foundation to install run-loop observers on your threads.
除了处理输入源之外,runloop还会生成关于runloop行为的通知。注册为runloop的观察者可以接收到这些通知。用他们在线程上做额外的处理。你应用核心基础框架在线程上安装runloop观察者。
The following sections provide more information about the components of a run loop and the modes in which they operate. They also describe the notifications that are generated at different times during the handling of events.
下边几个部分提供了runloop组件的更多信息,以及他们操作的那些模式。它们还描述了处理事件的不同时期生成的通知。
Run Loop Modes
runloop模式
A run loop mode is a collection of input sources and timers to be monitored and a collection of run loop observers to be notified. Each time you run your run loop, you specify (either explicitly or implicitly) a particular “mode” in which to run. During that pass of the run loop, only sources associated with that mode are monitored and allowed to deliver their events. (Similarly, only observers associated with that mode are notified of the run loop’s progress.) Sources associated with other modes hold on to any new events until subsequent passes through the loop in the appropriate mode.
runloop模式是一个输入源的集合,定时器会被监测,runloop观察者的集合将会受到通知。每次启动runloop的时候,你都会指定(显示或者隐示)跑的特定模式。在runloop通过期间,只有与该模式相关的源会被监听,允许处理事件。(相似的,只有与该模式结合的观察者会被通知runloop的进度)。与其他模式相结合的源会等待一些新的事件,直到后续相应的模式通过这个runloop。
In your code, you identify modes by name. Both Cocoa and Core Foundation define a default mode and several commonly used modes, along with strings for specifying those modes in your code. You can define custom modes by simply specifying a custom string for the mode name. Although the names you assign to custom modes are arbitrary, the contents of those modes are not. You must be sure to add one or more input sources, timers, or run-loop observers to any modes you create for them to be useful.
在你的代码中,你区分模式通过名字。Apple定义了默认模式和几种普通模式,在和特定的字符串绑定一起来使用。你可以通过字符串自定义模式名字。尽管你可以随意的定义模式的名字,但是模式的内容却不能随意定义。你必须确保添加一种或多种输入源,定时器,或者观察者带模式中使其有用。
You use modes to filter out events from unwanted sources during a particular pass through your run loop. Most of the time, you will want to run your run loop in the system-defined “default” mode. 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.
你可以使用模式在特定通过你的循环时,过滤不想要的事件。大多数情况下,你想要运行你的runloop在系统的默认模式。然而,一种形式的面板,可能以模态形式运行。当在这种模式的情况下,只有和模式面板相关的source才会将事件传递给线程。对于辅助线程,你可能用自定义的模式来阻止低优先级的source在时间紧迫的情况下传递事件。
Note:Modes discriminate based on the source of the event, not the type of the event. For example, you would not use modes to match only mouse-down events or only keyboard events. You could use modes to listen to a different set of ports, suspend timers temporarily, or otherwise change the sources and run loop observers currently being monitored.
注意:模式根据事件源来区分不是事件的类型。例如:你不会用模式来匹配仅有的鼠标事件或键盘事件。你可以用模式来监听不同的端口,临时暂停定时器,或者改变当前被监听的源和runloop的观察者。
Table 3-1 lists the standard modes defined by Cocoa and Core Foundation along with a description of when you use that mode. The name column lists the actual constants you use to specify the mode in your code.
下表列出了cocoa定义的几种标准模式,以及使用模式的描述。名称列列出了在特定模式下使用的常量。
默认模式:
默认模式使用操作最多的一个模式。大多数时候,你应该应用这个模式来开启的的runloop并配置输入源。
连接模式:
cocoa使用这个模式与NSConnection结合来监听回复。你应该很少用到这种模式。
语气模式:
cocoa使用这个模式来区分模式面板的事件。
事件追踪模式:
cocoa使用这种模式来限制在鼠标退拽和其他交互追踪过程中传入事件。
常用模式:
This is a configurable group of commonly used modes. Associating an input source with this mode also associates it with each of the modes in the group. For Cocoa applications, this set includes the default, modal, and event tracking modes by default. Core Foundation includes just the default mode initially. You can add custom modes to the set using the CFRunLoopAddCommonMode function.
这是一个可配置的常用模式组。结合输入源和这个模式也就是把它和组中的每个模式结合。对于cocoa程序,在默认情况下,这包括默认模式,语态模式以及事件追踪模式。核心框架中最初只包含默认模式。你可以使用CFRunLoopAddCommonMode,将自定义模式添加到组合中。
常见的使用:
我们定义轮播时,需要将定时器添加到common模式中。如果不这样做的话,拖动轮播的时候,由于跟踪模式会将其他source阻断,导致滑动时定时器会不走。添加到common模式中后,不会出现这种问题。因为common包含了跟踪模式和默认模式,这导致拖动时,定时器还在走不会阻断。