Input Sources
輸入源
Input sources deliver events asynchronously to your threads. The source of the event depends on the type of the input source, which is generally one of two categories. Port-based input sources monitor your application’s Mach ports. Custom input sources monitor custom sources of events. As far as your run loop is concerned, it should not matter whether an input source is port-based or custom. The system typically implements input sources of both types that you can use as is. The only difference between the two sources is how they are signaled. Port-based sources are signaled automatically by the kernel, and custom sources must be signaled manually from another thread.
輸入源會異步的傳遞事件給你的線程边臼。事件的來源取決于輸入源梯醒,這通常是兩個類別之一物邑〈辽保基于端口的輸入源監(jiān)聽你程序的硬件端口。自定義輸入源監(jiān)聽自定義事件源霎褐。就runloop而言陋葡,輸入源是基于端口還是自定義并不重要右莱。系統(tǒng)通常輸入源的各種類型桃笙,你可以使用氏堤。僅有的不同是如何發(fā)出信號〔鳎基于端口是由內(nèi)核發(fā)出信號鼠锈。自定義輸入源必須由另外一個線程發(fā)出信號。
When you create an input source, you assign it to one or more modes of your run loop. Modes affect which input sources are monitored at any given moment. Most of the time, you run the run loop in the default mode, but you can specify custom modes too. If an input source is not in the currently monitored mode, any events it generates are held until the run loop runs in the correct mode.
當你創(chuàng)建一個輸入源的時候熏瞄,你將給source分配你runloop里邊的一種或多種mode脚祟。mode會影響在給定時刻哪種source會被監(jiān)聽。大多數(shù)情況下强饮,你在默認模式下運行你的runloop。但是你也可以專門定義你的mode为黎。如果一個輸入源不在當前監(jiān)聽的mode邮丰,那么這個source生成的任何事件將保持行您,直到runloop以正確的mode運行。
注釋:簡單來說就是剪廉,runloop會以不同的mode運行娃循。在不同的mode下,source會發(fā)送不同的消息給程序進行處理斗蒋。如果不在runloop不在對應的mode下運行捌斧,就不發(fā)消息。例如滑動時泉沾,程序是在runloop跟蹤模式下運行捞蚂,那么默認mode對應的source就不會發(fā)消息給程序執(zhí)行。
The following sections describe some of the input sources.
下邊幾個部分描述幾種輸入源跷究。
Port-Based Sources
基于端口的源
Cocoa and Core Foundation provide built-in support for creating port-based input sources using port-related objects and functions. For example, in Cocoa, you never have to create an input source directly at all. You simply create a port object and use the methods ofNSPortto add that port to the run loop. The port object handles the creation and configuration of the needed input source for you.
cocoa和cocoa基礎架構cocoa用端口對象和函數(shù)為創(chuàng)建端口輸入源提供支持姓迅。例如,在cocoa中俊马,你從來不需要直接創(chuàng)建創(chuàng)建輸入源丁存。你只需要單單創(chuàng)建一個端口對象,添加它到runloop中即可柴我。端口對象幫你創(chuàng)建和配置所需的輸入源解寝。
In Core Foundation, you must manually create both the port and its run loop source. In both cases, you use the functions associated with the port opaque type (CFMachPortRef,CFMessagePortRef, orCFSocketRef) to create the appropriate objects.
在核心框架中,你必須手動創(chuàng)建端口和它的runloop源艘儒。在這兩種情況下聋伦,你使用和端口類型相關的函數(shù)來創(chuàng)建合適的對象。
Custom Input Sources
自定義輸入源
To create a custom input source, you must use the functions associated with the?CFRunLoopSourceRef?opaque type in Core Foundation. You configure a custom input source using several callback functions. Core Foundation calls these functions at different points to configure the source, handle any incoming events, and tear down the source when it is removed from the run loop.
在核心框架下彤悔,為了創(chuàng)建一個自定義輸入源嘉抓,你必須結合與CFRunLoopSourceRef相關的函數(shù)。你要用幾個回調(diào)函數(shù)來配置輸入源晕窑。核心基礎框架會在不同的點調(diào)用這些函數(shù)來配置這些源抑片,處理任何將要發(fā)生的事件。并在runloop刪除源時將其卸載。
In addition to defining the behavior of the custom source when an event arrives, you must also define the event delivery mechanism. 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.
當事件到達的時候除了要定義自定義源的行為财岔,你還必須定義事件傳遞機制厕鹃。source的這部分運行在單獨的線程上,源負責向輸入源提供數(shù)據(jù)植捎,并在數(shù)據(jù)處理好的時候發(fā)送給它。事件傳遞機制取決于你阳柔,沒必要過于復雜焰枢。
Cocoa Perform Selector Sources
cocoa執(zhí)行selector源
In addition to port-based sources, Cocoa defines a custom input source that allows you to perform a selector on any thread. Like a port-based source, perform selector requests are serialized on the target thread, alleviating many of the synchronization problems that might occur with multiple methods being run on one thread. Unlike a port-based source, a perform selector source removes itself from the run loop after it performs its selector.
除了基于端口的源,cocoa還定義了一個自定義輸入源,來允許你在任何線程上執(zhí)行方法济锄。像基于端口的源一樣暑椰,執(zhí)行選擇器請求在目標線程上被序列化,減輕了多個方法在一個線程上運行可能發(fā)生的許多同步問題荐绝。與基于端口的源不同一汽,執(zhí)行選擇器源會在執(zhí)行完后把它從runloop中移除。
When performing a selector on another thread, the target thread must have an active run loop. For threads you create, this means waiting until your code explicitly starts the run loop. Because the main thread starts its own run loop, however, you can begin issuing calls on that thread as soon as the application calls the applicationDidFinishLaunching:method of the application delegate. The run loop processes all queued perform selector calls each time through the loop, rather than processing one during each loop iteration.
當在另一個線程上執(zhí)行selector的時候低滩,目標線程必須有一個活躍的runloop召夹。對于你創(chuàng)建的線程,這意味著它會等到你的代碼中顯示的開始runloop恕沫。由于主線程啟動自己的runloop监憎。然而,一旦程序調(diào)用了didfinish方法昏兆,就可以在線程上發(fā)生調(diào)用枫虏。runloop在循環(huán)中每次執(zhí)行所有的選擇器,不是每次循環(huán)執(zhí)行一個爬虱。
Table 3-2 lists the methods defined onNSObject that can be used to perform selectors on other threads. Because these methods are declared onNSObject, you can use them from any threads where you have access to Objective-C objects, including POSIX threads. These methods do not actually create a new thread to perform the selector.
下表列出了NSObject上定義了在其他線程上可以用來執(zhí)行的方法隶债。由于這些方法定義在NSObject上,你可以應用他們在任何線程上跑筝,只要你可以訪問到oc對象死讹,包括POSIX。線程曲梗。這些方法實際上并沒有創(chuàng)建一個新的線程赞警。
Timer Sources
定時器源
Timer sources deliver events synchronously to your threads at a preset time in the future. Timers are a way for a thread to notify itself to do something. For example, a search field could use a timer to initiate an automatic search once a certain amount of time has passed between successive key strokes from the user. The use of this delay time gives the user a chance to type as much of the desired search string as possible before beginning the search.
定時器源會在預設的將來同步發(fā)送時間到你的線程。對于線程來說虏两,定時器是一種通知自己做事的一種方式愧旦。例如,用戶輸入一段時間定罢,你就可以自動搜索進行搜索笤虫。延遲時間的應用可以給用戶在開始搜索之前,有機會得到盡可能想要搜索的字符串祖凫。
Although it generates time-based notifications, a timer is not a real-time mechanism. Like input sources, timers are associated with specific modes of your run loop. If a timer is not in the mode currently being monitored by the run loop, it does not fire until you run the run loop in one of the timer’s supported modes. Similarly, if a timer fires when the run loop is in the middle of executing a handler routine, the timer waits until the next time through the run loop to its handler routine. If the run loop is not running at all, the timer never fires.
盡管定時源會生成基于定時器的通知琼蚯,但是定時器不是一種實時的機制。與輸入源一樣惠况,定時器也和runloop的模式相結合遭庶。如果一個定時器不屬于當前循環(huán)監(jiān)聽的模式,直到這個runloop運行定時器支持的模式才會啟動稠屠。相似的峦睡,如果當前的runloop正在處理其他事情翎苫,定時器觸發(fā),那么定時器會等到runloop下一次處理程序時赐俗。如果runloop沒有啟動拉队,那么定時器從來都不會開啟弊知。
You can configure timers to generate events only once or repeatedly. A repeating timer reschedules itself automatically based on the scheduled firing time, not the actual firing time. For example, if a timer is scheduled to fire at a particular time and every 5 seconds after that, the scheduled firing time will always fall on the original 5 second time intervals, even if the actual firing time gets delayed. If the firing time is delayed so much that it misses one or more of the scheduled firing times, the timer is fired only once for the missed time period. After firing for the missed period, the timer is rescheduled for the next scheduled firing time.
你可以配置定時器一次或者多次執(zhí)行阻逮。重復執(zhí)行會自動安排執(zhí)行按照設定的時間重新調(diào)度,不是實際開啟時間秩彤。例如叔扼,如果一個定時器運行在特定時間和之后每隔5秒。那么后邊盡管后邊實際開啟時間延誤了漫雷,但是預定時間依然是在原始的基礎上隔5秒瓜富。如果延誤太多,那么定時器會錯過一次或多次降盹,僅僅運行錯過時期的一次与柑。之后,將重新安排下一次的時間蓄坏。