Generated by GPT-5-mini| NSRunLoop | |
|---|---|
| Name | NSRunLoop |
| Platform | macOS, iOS, watchOS, tvOS |
| Language | Objective-C |
| Framework | Foundation (Apple) |
| First appeared | 2000s |
| Developer | Apple Inc. |
NSRunLoop
NSRunLoop is a core event-processing infrastructure in Apple's Foundation (Apple) framework that dispatches input sources and timers on threads. It coordinates with higher-level frameworks such as AppKit, UIKit, Core Foundation, and Grand Central Dispatch to manage event delivery, timer firing, and input-source handling for applications like those built for macOS, iOS, watchOS, and tvOS. Implementations interact with low-level primitives provided by POSIX, Mach (kernel), and CFRunLoop internals.
NSRunLoop provides a per-thread loop that waits for and dispatches events from sources such as port messages, sockets, and timer expirations. It acts as the integration point between frameworks like AppKit, UIKit, and system services such as CFNetwork, CoreAudio, and IOKit. Common use cases include coordinating UI updates in apps built with Xcode, scheduling work submitted from Grand Central Dispatch queues, and bridging with lower-level APIs exposed by Core Foundation and Cocoa (API).
The run loop architecture is composed of input sources, timers, observers, and modes. Input sources include port-based sources used by frameworks like Distributed Notifications and socket-based sources used by CFNetwork or custom POSIX sockets. Timers are built on top of system clock services and integrate with mechanisms such as mach_absolute_time for precision. Observers let frameworks like AppKit and UIKit monitor run loop transitions (entry, exit, before timers, before sources, after waiting). Modes partition event handling: standard application modes support interactive events, while custom modes support tasks like NSModalSession handling or UIScrollView tracking.
Typical APIs include instance methods to run the loop until a date or in a specific mode, methods to add and remove timers, and to schedule input sources. Patterns include: scheduling work on the main thread from background threads using performSelector:onThread:withObject:waitUntilDone:, posting work via NSNotificationCenter to trigger handlers on the appropriate run loop, and coordinating with NSOperationQueue for asynchronous tasks that require main-thread completion. Developers often use NSTimer for repeat scheduling, while high-performance I/O uses integration with CFRunLoopSource backed by CFSocket or direct Mach port messaging.
Each NSThread has an associated run loop; the main thread’s loop is used by UI frameworks like UIKit and AppKit. Background threads may not have a run loop running by default; starting a run loop enables handling of timers and input sources for background processing, commonly used in scenarios like background Core Data imports or AVFoundation processing. Run loop modes such as NSDefaultRunLoopMode, UITrackingRunLoopMode, and commonModes govern which sources are serviced, influencing behaviors in components like UIScrollView’s inertial scrolling, NSModalPanel modal sessions, and NSTimer delivery.
NSRunLoop is tightly integrated with Cocoa layers: AppKit relies on it for event dispatch on macOS windows and menus, while UIKit depends on it for touch, motion, and UI updates on iOS. Frameworks like Core Data and Foundation (Apple) use the run loop to schedule background save operations and merge notifications. Networking stacks such as NSURLSession and CFNetwork dispatch callbacks via run loop sources or Grand Central Dispatch bridges. Media and timing frameworks—Core Animation, AVFoundation, CoreMedia—use run loop timing or display-link mechanisms that cooperate with run loop cycles.
Minimize work performed on the main run loop to avoid UI jank in applications like those presented in App Store demos or Apple keynote samples. Offload CPU-bound tasks to Grand Central Dispatch global queues or NSOperationQueue and use run loop modes cautiously to prevent starvation of input sources. Coalesce timers when possible, prefer adaptive mechanisms like CADisplayLink for frame-tied updates, and use CFSocket with edge-triggered patterns for scalable networking akin to techniques used in Nginx or libuv-based servers. For energy efficiency on iOS devices, batch work and avoid frequent wake-ups that defeat system power management features.
Diagnose run loop stalls with tools such as Instruments (Apple), Xcode’s Main Thread Checker, and Activity Monitor sampling. Stack traces revealing long-running tasks on the main thread point to sources like expensive layout passes in Auto Layout or synchronous [network] calls from NSURLSession delegates. Use logging of run loop observer callbacks, enable thread sanitizer and address sanitizer in Xcode builds, and inspect CFRunLoopSource states when integrating with Cocoa (API) bridges. Community resources like Apple Developer Forums and talks from conferences such as WWDC provide practical debugging workflows.
Category:Apple APIs