An overview of the

Official runloop documentation

  • RunloopIs athreadAssociated infrastructure
  • RunloopIs an event processing loop used to schedule work and coordinate the receipt of incoming events
  • RunloopThe goal is to let go when there is work to be donethreadStay busy and let go when there is no workthreadFall asleep
  • RunloopManagement is not completely automatic in designthreadThe run loop must be started at the appropriate time
  • In the main threadRunloopIt 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 applications
  • Timer 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 sourcesThe asynchronous event is passed to the appropriate handler, causing the runUntilDate: method (called on the thread’s associated NSrunlop object) to exit
  • Timer sourcesPass 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 notify
  • Each 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 itNSPortMethod to add the port to the run loop
  • Configuring a Port-based Input Source

Custom Input Sources

  • To create a customThe input source, must be used with the core baseCFRunLoopSourceRefFunctions 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 threadSelector.
  • 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 SourcesEvents are delivered synchronously to the thread at a future preset time
  • TimerIt’s a way for a thread to tell itself to do something
  • It generates time-based notifications, butTimerIt’s not a real-time mechanic, soTimerMay not
  • withInput SourceAgain, timer andRunloopIs associated with a particular pattern
  • iftimerIs not in the mode currently monitored by the running looptimerSupports one of the modes to runrunLoopBefore, it wouldn’t start
  • Similarly, if a timer is inRunloopIs fired in the middle of executing a handlertimerWait until therunloopThe next time its handler is called. ifRunloopNot running at all, thentimerNever 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 ObserversinRunLoopFires at a special location during execution
  • You can useRun Loop ObserversTo prepare theThreadTo handle a given event, or inThreadPrepare before you fall asleepThread, we can takeRun Loop ObserverswithRunLoopIs associated with the following events:
  1. Enter theRunLoopWhen the
  2. whenRunLoopTo deal withTimerwhen
  3. whenRunloopTo deal withInput Sourcewhen
  4. whenRunLoopWhen you are about to fall asleep
  5. whenRunLoopWake up, but before it processes the event that woke it up
  6. whenRunLoopexit

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:

  1. noticeobserverHas entered theRunLoop
  2. noticeobserverReady to goTimerIs about to start
  3. noticeobserverAny non-port-based input source is about to fire.
  4. Start any non-port-based input source that is ready to be started.
  5. If the port-based input source is ready and waiting to fire, handle the event immediately. Go to Step 9
  6. noticeobserverThread about to sleep
  7. 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.
  8. Notifies the observer that the thread has just woken up.
  9. 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
  10. 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
  1. Communicate with other threads using ports or custom input sources
  2. Use timers on threads.
  3. Use any PerformSelect in Cocoa applications… methods
  4. 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.