The NSRunLoop
class declares the programmatic interface to objects that manage input sources. An NSRunLoop
object processes input for sources such as mouse and keyboard events from the window system, NSPort
objects, and NSConnection
objects. An NSRunLoop
object also processes NSTimer
events.
Your application cannot either create or explicitly manage NSRunLoop objects. Each NSThread
object, including the application’s main thread, has an NSRunLoop
object automatically created for it as needed. If you need to access the current thread’s run loop, you do so with the class method currentRunLoop
.
Note that from the perspective of NSRunloop
, NSTimer
objects are not "input"—they are a special type, and one of the things that means is that they do not cause the run loop to return when they fire.
注意:
NSRunLoop通常不被认为是线程安全的,并且只应该在当前线程的上下文环境中调用它的方法。不要尝试在另一个不同的线程中调用NSRunLoop对象的方法,这样做可能造成未知的错误。
Timer和NSRunLoop结合工作,但他们不能提供一个真正的时间机制,准确性受限。如果你只是想在未来的某个时间点发送一个消息,可以不用timer,Timer就是NSTimer对象。
Timers are represented by NSTimer
objects. They work in conjunction with NSRunLoop
objects. NSRunLoop
objects control loops that wait for input, and they use timers to help determine the maximum amount of time they should wait. When the timer’s time limit has elapsed, the run loop fires the timer (causing its message to be sent), then checks for new input.
The run loop mode in which you register the timer must be running for the timer to fire. For applications built using the Application Kit or UIKit, the application object runs the main thread’s run loop for you. On secondary threads, however, you have to run the run loop yourself.
RunLoop是和线程相关的基础设施。一个runloop是一个时间处理loop,你可以安排工作、协调the receipt of incoming events。runloop的目的是有工作的时候,让线程忙,没有工作,就让线程sleep。
Run loop管理不是完全自动的。你必须设计你的线程代码,在合适的时间启动run loop,并相应到来的事件。Cocoa和Core Foundation提供runloop对象帮助你配置管理你的线程的runloop。你的应用程序没有必要显式的创建这些对象;每个线程(包括应用程序主线程)有一个关联的runloop对象。只有secondar thread需要显式运行他们的runloop。app框架(frameworks)在主线程自动启动并运行runloop,作为程序启动进程的一部分。
Anatomy of a Run Loop
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.
run loop从两种不同类型的源接收事件。Input sources deliver异步事件,通常是从另一个线程或一个不同应用的消息。Timer source deliver ,不多解释了。这两种源到达时,都使用应用程序特定处理路径。
下面的图3-1显示了run loop概念上的结构和各种源(source)。Input source deliver异步事件给合适的处理者,并造成 runUntilDate: 方法(被和线程相关的runloop对象调用)退出。Timer source deliver events to their handler routines(理解,翻译不通,有个懂英语的妹子多好),但不会造成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组件和模式的信息,也描述了在处理事件的不同时间,生成的通知。
Run Loop Modes
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 you run loop, you specify(显式或隐式指定都行)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.(关键的东西不敢乱翻译啊,胆小)
在你的代码里,通过名字来区别不同的模式(modes)。Cocoa和Core Foundation定义一个默认的和几个常用的模式。你可以自定义模式,通过为模式的名字指定一个字符串。模式的名字可以随便起,但内容不能。你要确保一个或者更多input sources、timers或者run-loop观察者被加到你创建的模式中。
You use modes to filter out events from unwanted sources during a particular pass through your run loop. Most of time, you will want to run you run loop in the system-defined "default" mode. A modal panel, however, might run in the "modal" mode. While in this mode, only sources revevant to the model 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.
注意: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.
消化消化,吃饭去。有时间继续