Painted painted levels: fostered fostered fostered

IOS RunLoop Thread Resident

Preface:

This article introduces some of the concepts and uses of RunLoop: using RunLoop to create resident threads, customizing input sources for thread communication, etc. At the same time, I hope to take this opportunity to discuss runloop-related knowledge with you and deepen your understanding of RunLoop.

What is RunLoop?

A RunLoop is part of the thread-related infrastructure. It is a loop that handles events (threads enter this loop and run event handlers in response to incoming events). The purpose of a RunLoop is to keep threads active and busy when there are events to handle, and to sleep when there are no events.

RunLoop structure and event source:

A RunLoop contains several Mode, each Mode contains a number of Source/Timer/Observer/Port. When starting a RunLoop, a Mode is first specified and checked to see if the specified Mode exists and if the Mode contains Source and Timer. If the Mode does not exist or if the Mode does not contain Source and Timer, the Mode is considered to be an empty Mode and the RunLoop exits directly.

The Input Source:
  • Port-based Sources: monitors the Mach Port of the App, sends signals by the kernel, and executes relevant routines after receiving signals from the input source.

  • Custom Input Sources: listens to user-defined Input Sources. After other threads send signals manually, the Input source executes related routines.

  • Cocoa Perform Selector Sources: A custom input source in Cocoa that is used to execute tasks in different threads. Tasks in the same thread are executed sequentially. When the tasks are completed, the system automatically removes this source. (Note: To execute a task in a target thread, the target thread must have an active RunLoop)

The Timer Source:

A time source passes events to the corresponding thread at a preset time synchronization, and a timer is a thread’s way of telling itself to do something.

Timers are not really real-time. Timers do not schedule tasks when they are not in the Mode the RunLoop is currently listening to. Timers only start tasks when the Mode the RunLoop is currently listening to is the Mode associated with the timer, for example: NSTimer is added to the DefaultMode of the main RunLoop. When you slide TableView/ScrollView, the RunLoop switches to TrackMode and the timer does not schedule tasks.

If RunLoop is executing a routine and the timer fires, the timer waits for the RunLoop to complete the routine and process it in the next loop. In the absence of RunLoop, the timer never fires the task.

How to use RunLoop?

[[NSRunLoop currentRunLoop] runUntilDate:] [NSRunLoop currentRunLoop] runUntilDate:] [NSRunLoop currentRunLoop] runUntilDate:] [NSRunLoop currentRunLoop] runUntilDate:] [NSRunLoop currentRunLoop] runUntilDate:] So what happens if we show that we call RunLoop’s run method on the main thread? As shown in the Demo, starting RunLoop in the main thread will affect the current event processing, but since RunLoop does not stop, other events can be received and processed normally.

The child thread does not have to be set up to run RunLoop to execute a task, such as simply processing a time-consuming task in the child thread.

  1. useNSPortOr custom input sources that communicate with other threads.
  2. Use timers on threads.
  3. In aCocoaUse in applicationperformSelectorRelated methods.
  4. Make a thread resident, in which tasks are executed periodically.

As mentioned in the introduction, this article focuses on thread resident and custom input source thread communication.

Thread resident:

Option 1: Starting a RunLoop unconditionally is the easiest option, but it’s also the least desirable. It puts the thread in a permanent loop, giving it little control over the RunLoop itself. Input sources and timers can be added and removed, but the only way to stop the RunLoop is to kill the RunLoop. In fact, during my experiment, I found that the CANCEL method of NSThread could not be used to stop the RunLoop. The cancel method changes the cancellation status of the thread, indicating that it should exit. Under the current thread to perform [NSThread exit] method, withdrew from the thread, but in the demo LongLifeThreadViewController still has not been released)

Method 2: Set a time limit when starting RunLoop. The RunLoop will run until the event arrives or the allotted time expires. If the event arrives, it is dispatched to the handler for processing, and then exits the RunLoop. The next event can be processed by restarting RunLoop. Also, if the allotted time expires, you can restart RunLoop to process it. This allows you to specify RunLoopMode, which is recommended by the official website.

Custom input source thread communication:

Define the input source:

  1. Provides information for the input source to process.
  2. The execution routine when an event is received.
  3. The input source adds toRunLoopThe execution routine of.
  4. Execution routines when the input source fails.

You can decide whether to implement content 3 and 4 based on your personal needs. (Note that defining the input source can only be done through the corresponding API provided by CoreFoundation, where the callback routine is implemented in C.)

Install input sources on RunLoop: If item 3 above is implemented, the schedule implementation routine corresponding to the input source is called back when a custom input source is added to the RunLoop.

Signal to the input source: Upon receiving the signal, the input source executes the corresponding Perform routine, which is the corresponding event handler. (Note that if the thread is asleep, wake it up, otherwise the event cannot be processed.


Conclusion:

There is more to RunLoop, such as: RunLoopModes, RunLoopObserver, NSPort, NSTimer, etc., as well as the source code of RunLoop, these contents are not listed here, if you are interested in partners can take the time to explore, learn, then can communicate and discuss together.

Source code address: QiRunLoopDemo1


Recommended articles:

Common iOS debugging methods: LLDB command Common iOS debugging methods: breakpoint Common iOS debugging methods: static analysis iOS message forwarding iOS custom drag-and-drop control: QiDragView iOS custom card control: QiCardView iOS Wireshark Capture iOS Charles Capture Bag dance weekly