An overview of the
Official runloop documentation
Runloop
Is athread
Associated infrastructureRunloop
Is an event processing loop used to schedule work and coordinate the receipt of incoming eventsRunloop
The goal is to let go when there is work to be donethread
Stay busy and let go when there is no workthread
Fall asleepRunloop
Management is not completely automatic in designthread
The run loop must be started at the appropriate time- In the main thread
Runloop
It is automatically started and must be manually started in child threads
Runloop parsing
RunLoop accepts events from the Input sources Input source and Timer Sources clock source
Input sources
: sends asynchronous events, mainly from other threads or applicationsTimer sources
: sends synchronization events that occur at predetermined times or repeated time intervals (occurring at a scheduled time or repeating interval
)
This is summed up in a diagram on the official website showing the conceptual structure of Runloop and various sources
Input sources
The asynchronous event is passed to the appropriate handler, causing the runUntilDate: method (called on the thread’s associated NSrunlop object) to exitTimer sources
Pass events to its handler routines without causing the run loop to exit
RunLoop Mode
RunLoop Mode
: is a collection of input sources and timers to monitor, and running loop observers to notifyEach time the RUN loop is run, a specific "mode" is specified (explicitly or implicitly) to run
During this part of the running cycle, only the sources associated with the pattern are monitored and allowed to deliver their events
Type of schema
-
NSDefaultRunLoopMode: Default mode. This mode is generally used
-
NSConnectionReplyMode: This mode is used in conjunction with NSConnection objects to monitor replies
-
NSModalPanelRunLoopMode: Use this mode to identify events for the modal panel
-
NSEventTrackingRunLoopMode: use this Mode to track events from the user interaction, such as: UIScrollView slide up and down
-
NSRunLoopCommonModes: This is a combination of modes that by default include default, modal, and event tracking modes
Although 5 modes are defined in the official documentation, only NSDefaultRunLoopMode and NSRunLoopCommonModes are exposed in iOS
Input Source
The input source passes events asynchronously to the thread. The source of the event depends on the type of input source, which is usually one of two types. Port-based input sources monitor the Mach port of the application. Custom input sources monitor custom event sources. It does not matter whether the input source is port-based or custom for the running loop. Systems typically implement two types of input sources that you can use as-is. The only difference between the two sources is the way they signal. Port-based sources are automatically signaled by the kernel, while custom sources must be signaled manually from another thread
Port-based Sources(port-based Sources)
- In Cocoa, you don’t need to create an input source directly at all, you just create a port object and use it
NSPort
Method to add the port to the run loop - Configuring a Port-based Input Source
Custom Input Sources
- To create a custom
The input source
, must be used with the core baseCFRunLoopSourceRef
Functions associated with opaque types. - Custom input sources can be configured using several callback functions that Core Foundation calls at different points to configure the source, handle any incoming events, and dismantle the source when it is removed from the run loop.
- For example how to create a Custom Input Source, Defining a Custom Input Source
Cocoa Perform Selector Sources
- In addition to port-based sources, Cocoa defines a custom input source that allows you to execute on any thread
Selector
. - As with port-based sources, requests that execute selectors are serialized on the thread, alleviating many of the synchronization problems that can occur when multiple methods are run on a single thread
- Unlike port-based sources, the executing selector source removes itself from the run loop after executing its selector.
performSelectorOnMainThread:withObject:waitUntilDone:
performSelectorOnMainThread:withObject:waitUntilDone:modes:
In the next run cycle of the main thread of an application, executes the specified selector on that thread. These methods allow you to block the current thread before executing the selector.
performSelector:onThread:withObject:waitUntilDone:
performSelector:onThread:withObject:waitUntilDone:modes:
Executes the specified selector on any thread that has an NSThread object. These methods allow you to block the current thread before executing the selector.
performSelector:withObject:afterDelay:
performSelector:withObject:afterDelay:inModes:
Executes the specified selector on the current thread after the next run cycle and optional delay period. Because it waits until the next run cycle to execute the selector, these methods provide an automatic minimum delay from currently executing code. Multiple queue selectors are executed in their queue order
cancelPreviousPerformRequestsWithTarget:
cancelPreviousPerformRequestsWithTarget:selector:object:
To cancel a through performSelector: withObject: afterDelay: and performSelector: withObject: afterDelay: inModes: send a message,
Timer Sources
Timer Sources
Events are delivered synchronously to the thread at a future preset timeTimer
It’s a way for a thread to tell itself to do something- It generates time-based notifications, but
Timer
It’s not a real-time mechanic, soTimer
May not - with
Input Source
Again, timer andRunloop
Is associated with a particular pattern - if
timer
Is not in the mode currently monitored by the running looptimer
Supports one of the modes to runrunLoop
Before, it wouldn’t start - Similarly, if a timer is in
Runloop
Is fired in the middle of executing a handlertimer
Wait until therunloop
The next time its handler is called. ifRunloop
Not running at all, thentimer
Never trigger
For more information about Configuring Timer Sources, see Configuring Timer Sources, NSTimer Class Reference and CFRunLoop Timer Reference
Run Loop Observers
- Unlike the source that fires when an appropriate asynchronous or synchronous event occurs,
Run Loop Observers
inRunLoop
Fires at a special location during execution - You can use
Run Loop Observers
To prepare theThread
To handle a given event, or inThread
Prepare before you fall asleepThread
, we can takeRun Loop Observers
withRunLoop
Is associated with the following events:
- Enter the
RunLoop
When the - when
RunLoop
To deal withTimer
when - when
Runloop
To deal withInput Source
when - when
RunLoop
When you are about to fall asleep - when
RunLoop
Wake up, but before it processes the event that woke it up - when
RunLoop
exit
To create a running loop observer, you need to create a new instance of the CFRunLoopObserverRef opaque type.
The Run Loop Sequence of Events
Each time it runs, the thread’s RunLoop handles pending events and generates notifications for any connected observer. It does so in a very specific order, as follows:
- notice
observer
Has entered theRunLoop
- notice
observer
Ready to goTimer
Is about to start - notice
observer
Any non-port-based input source is about to fire. - Start any non-port-based input source that is ready to be started.
- If the port-based input source is ready and waiting to fire, handle the event immediately. Go to Step 9
- notice
observer
Thread about to sleep - Put the thread to sleep until one of the following events occurs:
- Event arrival of the port-based input source.
- The timer starts.
- The timeout value set for the run loop expires.
- The run loop is awakened explicitly.
- Notifies the observer that the thread has just woken up.
- Handle pending events.
- If a user-defined timer is triggered, handle the timer event and restart the loop. Go to Step 2
- If the input source is fired, the event is passed.
- If the run loop is awakened explicitly but has not timed out, restart the loop. Go to Step 2
- Notify the observer that the run loop has exited
Summarize the above process with a diagram:
When Would You Use a Run Loop?
- The only time you need to explicitly run a run loop is when you create child threads for your application
- The main thread runloop is automatically created by the system
- Communicate with other threads using ports or custom input sources
- Use timers on threads.
- Use any PerformSelect in Cocoa applications… methods
- Thread to keep alive
In conclusion, this article is based on a translation of apple’s official documentation and explains some of the theoretical concepts of Runloop.