运行循环和重绘视图
iOS应用启动时会开始一个运行循环(run loop)。
运行循环的工作方式是监听事件,例如触摸。
当事件发生时,运行循环会为相应的事件找到合适的处理方法。这些处理方法会调用其他方法,而这些方法又会调用更多其他方法,以此类推。
只有当这些方法都执行完毕时,控制权才会再次回到运行循环。
当应用将控制权交回给运行循环时,运行循环首先检查是否有等待重绘的视图(即在当前循环收到过 setNeedsDisplay 消息的视图),然后向所有等待重绘的视图发送DrawRect:消息,最后视图层次结构中所有视图的图层再次组合成一副完整地图像并绘制到屏幕上。
如下图1:
iOS做了两方面优化来保证用户界面的流畅性 -- 不重绘显示的内容没有改变的视图;在每次事件事件处理周期(event handling cycle)中只发送一次drawRect:消息。在事件处理周期中,视图的属性可能会发生多次改变,如果视图在每次属性改变时都重绘自己,就会减慢界面的响应速度。相反,iOS会在运行循环的最后阶段集中处理所有需要重绘的视图,尤其是对于属性发生多次改变的视图,在每次事件处理周期中只重绘一次。
以上摘自 BNR版《iOS编程》第四版 P113
Run Loop Concept
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.
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.
Figure 3-1 shows 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 associated NSRunLoop
object) to exit. Timer sources deliver events to their handler routines but do not cause the run loop to exit.